167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: nsxfname - Public interfaces to the ACPI subsystem 467754Smsmith * ACPI Namespace oriented interfaces 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 8217365Sjkim/* 9306536Sjkim * Copyright (C) 2000 - 2016, 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 45281075Sdim#define EXPORT_ACPI_INTERFACES 4667754Smsmith 47193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 48193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 51193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 5267754Smsmith 5367754Smsmith 5477424Smsmith#define _COMPONENT ACPI_NAMESPACE 5591116Smsmith ACPI_MODULE_NAME ("nsxfname") 5667754Smsmith 57197104Sjkim/* Local prototypes */ 5867754Smsmith 59197104Sjkimstatic char * 60197104SjkimAcpiNsCopyDeviceId ( 61241973Sjkim ACPI_PNP_DEVICE_ID *Dest, 62241973Sjkim ACPI_PNP_DEVICE_ID *Source, 63197104Sjkim char *StringArea); 64197104Sjkim 65197104Sjkim 66117521Snjl/****************************************************************************** 6767754Smsmith * 6867754Smsmith * FUNCTION: AcpiGetHandle 6967754Smsmith * 7067754Smsmith * PARAMETERS: Parent - Object to search under (search scope). 71151937Sjkim * Pathname - Pointer to an asciiz string containing the 72151937Sjkim * name 73151937Sjkim * RetHandle - Where the return handle is returned 7467754Smsmith * 7567754Smsmith * RETURN: Status 7667754Smsmith * 7767754Smsmith * DESCRIPTION: This routine will search for a caller specified name in the 78241973Sjkim * name space. The caller can restrict the search region by 79241973Sjkim * specifying a non NULL parent. The parent value is itself a 8067754Smsmith * namespace handle. 8167754Smsmith * 8267754Smsmith ******************************************************************************/ 8367754Smsmith 8467754SmsmithACPI_STATUS 8567754SmsmithAcpiGetHandle ( 8667754Smsmith ACPI_HANDLE Parent, 8767754Smsmith ACPI_STRING Pathname, 8867754Smsmith ACPI_HANDLE *RetHandle) 8967754Smsmith{ 9067754Smsmith ACPI_STATUS Status; 9169450Smsmith ACPI_NAMESPACE_NODE *Node = NULL; 9267754Smsmith ACPI_NAMESPACE_NODE *PrefixNode = NULL; 9367754Smsmith 9467754Smsmith 9591116Smsmith ACPI_FUNCTION_ENTRY (); 9683174Smsmith 9783174Smsmith 9877424Smsmith /* Parameter Validation */ 9977424Smsmith 10067754Smsmith if (!RetHandle || !Pathname) 10167754Smsmith { 10267754Smsmith return (AE_BAD_PARAMETER); 10367754Smsmith } 10467754Smsmith 10569746Smsmith /* Convert a parent handle to a prefix node */ 10669746Smsmith 10767754Smsmith if (Parent) 10867754Smsmith { 109200553Sjkim PrefixNode = AcpiNsValidateHandle (Parent); 11069450Smsmith if (!PrefixNode) 11167754Smsmith { 11267754Smsmith return (AE_BAD_PARAMETER); 11367754Smsmith } 114167802Sjkim } 11567754Smsmith 116167802Sjkim /* 117167802Sjkim * Valid cases are: 118167802Sjkim * 1) Fully qualified pathname 119167802Sjkim * 2) Parent + Relative pathname 120167802Sjkim * 121167802Sjkim * Error for <null Parent + relative path> 122167802Sjkim */ 123245582Sjkim if (ACPI_IS_ROOT_PREFIX (Pathname[0])) 124167802Sjkim { 125167802Sjkim /* Pathname is fully qualified (starts with '\') */ 126167802Sjkim 127167802Sjkim /* Special case for root-only, since we can't search for it */ 128167802Sjkim 129306536Sjkim if (!strcmp (Pathname, ACPI_NS_ROOT_PATH)) 13091116Smsmith { 131200553Sjkim *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, AcpiGbl_RootNode); 132167802Sjkim return (AE_OK); 13391116Smsmith } 13467754Smsmith } 135167802Sjkim else if (!PrefixNode) 136167802Sjkim { 137167802Sjkim /* Relative path with null prefix is disallowed */ 13867754Smsmith 139167802Sjkim return (AE_BAD_PARAMETER); 14067754Smsmith } 14167754Smsmith 142167802Sjkim /* Find the Node and convert to a handle */ 14367754Smsmith 144167802Sjkim Status = AcpiNsGetNode (PrefixNode, Pathname, ACPI_NS_NO_UPSEARCH, &Node); 14569746Smsmith if (ACPI_SUCCESS (Status)) 14667754Smsmith { 147200553Sjkim *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, Node); 14867754Smsmith } 14967754Smsmith 15067754Smsmith return (Status); 15167754Smsmith} 15267754Smsmith 153167802SjkimACPI_EXPORT_SYMBOL (AcpiGetHandle) 15467754Smsmith 155167802Sjkim 156117521Snjl/****************************************************************************** 15767754Smsmith * 15883174Smsmith * FUNCTION: AcpiGetName 15967754Smsmith * 16067754Smsmith * PARAMETERS: Handle - Handle to be converted to a pathname 16167754Smsmith * NameType - Full pathname or single segment 16291116Smsmith * Buffer - Buffer for returned path 16367754Smsmith * 16467754Smsmith * RETURN: Pointer to a string containing the fully qualified Name. 16567754Smsmith * 16667754Smsmith * DESCRIPTION: This routine returns the fully qualified name associated with 167241973Sjkim * the Handle parameter. This and the AcpiPathnameToHandle are 16867754Smsmith * complementary functions. 16967754Smsmith * 17067754Smsmith ******************************************************************************/ 17167754Smsmith 17267754SmsmithACPI_STATUS 17367754SmsmithAcpiGetName ( 17467754Smsmith ACPI_HANDLE Handle, 17567754Smsmith UINT32 NameType, 17691116Smsmith ACPI_BUFFER *Buffer) 17767754Smsmith{ 17867754Smsmith ACPI_STATUS Status; 17967754Smsmith ACPI_NAMESPACE_NODE *Node; 180306536Sjkim const char *NodeName; 18167754Smsmith 18267754Smsmith 18391116Smsmith /* Parameter validation */ 18467754Smsmith 18591116Smsmith if (NameType > ACPI_NAME_TYPE_MAX) 18667754Smsmith { 18767754Smsmith return (AE_BAD_PARAMETER); 18867754Smsmith } 18967754Smsmith 19091116Smsmith Status = AcpiUtValidateBuffer (Buffer); 19191116Smsmith if (ACPI_FAILURE (Status)) 19267754Smsmith { 19391116Smsmith return (Status); 19467754Smsmith } 19567754Smsmith 196306536Sjkim if (NameType == ACPI_FULL_PATHNAME || 197306536Sjkim NameType == ACPI_FULL_PATHNAME_NO_TRAILING) 19867754Smsmith { 19967754Smsmith /* Get the full pathname (From the namespace root) */ 20067754Smsmith 201306536Sjkim Status = AcpiNsHandleToPathname (Handle, Buffer, 202306536Sjkim NameType == ACPI_FULL_PATHNAME ? FALSE : TRUE); 20367754Smsmith return (Status); 20467754Smsmith } 20567754Smsmith 20667754Smsmith /* 20767754Smsmith * Wants the single segment ACPI name. 20891116Smsmith * Validate handle and convert to a namespace Node 20967754Smsmith */ 21091116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 21191116Smsmith if (ACPI_FAILURE (Status)) 21291116Smsmith { 21391116Smsmith return (Status); 21491116Smsmith } 21591116Smsmith 216200553Sjkim Node = AcpiNsValidateHandle (Handle); 21767754Smsmith if (!Node) 21867754Smsmith { 21967754Smsmith Status = AE_BAD_PARAMETER; 22067754Smsmith goto UnlockAndExit; 22167754Smsmith } 22267754Smsmith 22391116Smsmith /* Validate/Allocate/Clear caller buffer */ 22467754Smsmith 225114237Snjl Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH); 22691116Smsmith if (ACPI_FAILURE (Status)) 22767754Smsmith { 22867754Smsmith goto UnlockAndExit; 22967754Smsmith } 23067754Smsmith 23167754Smsmith /* Just copy the ACPI name from the Node and zero terminate it */ 23267754Smsmith 233252279Sjkim NodeName = AcpiUtGetNodeName (Node); 234252279Sjkim ACPI_MOVE_NAME (Buffer->Pointer, NodeName); 235114237Snjl ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0; 23667754Smsmith Status = AE_OK; 23767754Smsmith 23867754Smsmith 23967754SmsmithUnlockAndExit: 24067754Smsmith 24191116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 24267754Smsmith return (Status); 24367754Smsmith} 24467754Smsmith 245167802SjkimACPI_EXPORT_SYMBOL (AcpiGetName) 24667754Smsmith 247167802Sjkim 248117521Snjl/****************************************************************************** 24967754Smsmith * 250197104Sjkim * FUNCTION: AcpiNsCopyDeviceId 251197104Sjkim * 252241973Sjkim * PARAMETERS: Dest - Pointer to the destination PNP_DEVICE_ID 253241973Sjkim * Source - Pointer to the source PNP_DEVICE_ID 254197104Sjkim * StringArea - Pointer to where to copy the dest string 255197104Sjkim * 256197104Sjkim * RETURN: Pointer to the next string area 257197104Sjkim * 258241973Sjkim * DESCRIPTION: Copy a single PNP_DEVICE_ID, including the string data. 259197104Sjkim * 260197104Sjkim ******************************************************************************/ 261197104Sjkim 262197104Sjkimstatic char * 263197104SjkimAcpiNsCopyDeviceId ( 264241973Sjkim ACPI_PNP_DEVICE_ID *Dest, 265241973Sjkim ACPI_PNP_DEVICE_ID *Source, 266197104Sjkim char *StringArea) 267197104Sjkim{ 268241973Sjkim /* Create the destination PNP_DEVICE_ID */ 269241973Sjkim 270197104Sjkim Dest->String = StringArea; 271197104Sjkim Dest->Length = Source->Length; 272197104Sjkim 273197104Sjkim /* Copy actual string and return a pointer to the next string area */ 274197104Sjkim 275306536Sjkim memcpy (StringArea, Source->String, Source->Length); 276197104Sjkim return (StringArea + Source->Length); 277197104Sjkim} 278197104Sjkim 279197104Sjkim 280197104Sjkim/****************************************************************************** 281197104Sjkim * 28267754Smsmith * FUNCTION: AcpiGetObjectInfo 28367754Smsmith * 284197104Sjkim * PARAMETERS: Handle - Object Handle 285197104Sjkim * ReturnBuffer - Where the info is returned 28667754Smsmith * 28767754Smsmith * RETURN: Status 28867754Smsmith * 28967754Smsmith * DESCRIPTION: Returns information about an object as gleaned from the 29067754Smsmith * namespace node and possibly by running several standard 29167754Smsmith * control methods (Such as in the case of a device.) 29267754Smsmith * 293306536Sjkim * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA, 294306536Sjkim * _CLS, _ADR, _SxW, and _SxD methods. 295197104Sjkim * 296197104Sjkim * Note: Allocates the return buffer, must be freed by the caller. 297197104Sjkim * 298306536Sjkim * Note: This interface is intended to be used during the initial device 299306536Sjkim * discovery namespace traversal. Therefore, no complex methods can be 300306536Sjkim * executed, especially those that access operation regions. Therefore, do 301306536Sjkim * not add any additional methods that could cause problems in this area. 302306536Sjkim * this was the fate of the _SUB method which was found to cause such 303306536Sjkim * problems and was removed (11/2015). 304306536Sjkim * 30567754Smsmith ******************************************************************************/ 30667754Smsmith 30767754SmsmithACPI_STATUS 30867754SmsmithAcpiGetObjectInfo ( 30967754Smsmith ACPI_HANDLE Handle, 310197104Sjkim ACPI_DEVICE_INFO **ReturnBuffer) 31167754Smsmith{ 31267754Smsmith ACPI_NAMESPACE_NODE *Node; 313151937Sjkim ACPI_DEVICE_INFO *Info; 314241973Sjkim ACPI_PNP_DEVICE_ID_LIST *CidList = NULL; 315241973Sjkim ACPI_PNP_DEVICE_ID *Hid = NULL; 316241973Sjkim ACPI_PNP_DEVICE_ID *Uid = NULL; 317306536Sjkim ACPI_PNP_DEVICE_ID *Cls = NULL; 318197104Sjkim char *NextIdString; 319197104Sjkim ACPI_OBJECT_TYPE Type; 320197104Sjkim ACPI_NAME Name; 321197104Sjkim UINT8 ParamCount= 0; 322306536Sjkim UINT16 Valid = 0; 323197104Sjkim UINT32 InfoSize; 324197104Sjkim UINT32 i; 325197104Sjkim ACPI_STATUS Status; 32667754Smsmith 32767754Smsmith 32867754Smsmith /* Parameter validation */ 32967754Smsmith 330197104Sjkim if (!Handle || !ReturnBuffer) 33167754Smsmith { 33267754Smsmith return (AE_BAD_PARAMETER); 33367754Smsmith } 33467754Smsmith 33591116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 33691116Smsmith if (ACPI_FAILURE (Status)) 33791116Smsmith { 338243347Sjkim return (Status); 33991116Smsmith } 34067754Smsmith 341200553Sjkim Node = AcpiNsValidateHandle (Handle); 34267754Smsmith if (!Node) 34367754Smsmith { 34491116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 345197104Sjkim return (AE_BAD_PARAMETER); 34667754Smsmith } 34767754Smsmith 348197104Sjkim /* Get the namespace node data while the namespace is locked */ 34967754Smsmith 350197104Sjkim InfoSize = sizeof (ACPI_DEVICE_INFO); 351197104Sjkim Type = Node->Type; 352197104Sjkim Name = Node->Name.Integer; 353117521Snjl 354193267Sjkim if (Node->Type == ACPI_TYPE_METHOD) 355193267Sjkim { 356197104Sjkim ParamCount = Node->Object->Method.ParamCount; 357193267Sjkim } 358193267Sjkim 35991116Smsmith Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 36091116Smsmith if (ACPI_FAILURE (Status)) 36191116Smsmith { 362197104Sjkim return (Status); 36391116Smsmith } 36467754Smsmith 365197104Sjkim if ((Type == ACPI_TYPE_DEVICE) || 366197104Sjkim (Type == ACPI_TYPE_PROCESSOR)) 36767754Smsmith { 368117521Snjl /* 369197104Sjkim * Get extra info for ACPI Device/Processor objects only: 370306536Sjkim * Run the Device _HID, _UID, _CLS, and _CID methods. 371123315Snjl * 372117521Snjl * Note: none of these methods are required, so they may or may 373197104Sjkim * not be present for this device. The Info->Valid bitfield is used 374197104Sjkim * to indicate which methods were found and run successfully. 375117521Snjl */ 37667754Smsmith 377117521Snjl /* Execute the Device._HID method */ 37867754Smsmith 379197104Sjkim Status = AcpiUtExecute_HID (Node, &Hid); 380117521Snjl if (ACPI_SUCCESS (Status)) 381117521Snjl { 382197104Sjkim InfoSize += Hid->Length; 383197104Sjkim Valid |= ACPI_VALID_HID; 384117521Snjl } 38567754Smsmith 386117521Snjl /* Execute the Device._UID method */ 38767754Smsmith 388197104Sjkim Status = AcpiUtExecute_UID (Node, &Uid); 389117521Snjl if (ACPI_SUCCESS (Status)) 390117521Snjl { 391197104Sjkim InfoSize += Uid->Length; 392197104Sjkim Valid |= ACPI_VALID_UID; 393117521Snjl } 394117521Snjl 395117521Snjl /* Execute the Device._CID method */ 396117521Snjl 397117521Snjl Status = AcpiUtExecute_CID (Node, &CidList); 398117521Snjl if (ACPI_SUCCESS (Status)) 399117521Snjl { 400197104Sjkim /* Add size of CID strings and CID pointer array */ 401197104Sjkim 402241973Sjkim InfoSize += (CidList->ListSize - sizeof (ACPI_PNP_DEVICE_ID_LIST)); 403197104Sjkim Valid |= ACPI_VALID_CID; 404117521Snjl } 405306536Sjkim 406306536Sjkim /* Execute the Device._CLS method */ 407306536Sjkim 408306536Sjkim Status = AcpiUtExecute_CLS (Node, &Cls); 409306536Sjkim if (ACPI_SUCCESS (Status)) 410306536Sjkim { 411306536Sjkim InfoSize += Cls->Length; 412306536Sjkim Valid |= ACPI_VALID_CLS; 413306536Sjkim } 414197104Sjkim } 415117521Snjl 416197104Sjkim /* 417197104Sjkim * Now that we have the variable-length data, we can allocate the 418197104Sjkim * return buffer 419197104Sjkim */ 420197104Sjkim Info = ACPI_ALLOCATE_ZEROED (InfoSize); 421197104Sjkim if (!Info) 422197104Sjkim { 423197104Sjkim Status = AE_NO_MEMORY; 424197104Sjkim goto Cleanup; 425197104Sjkim } 426197104Sjkim 427197104Sjkim /* Get the fixed-length data */ 428197104Sjkim 429197104Sjkim if ((Type == ACPI_TYPE_DEVICE) || 430197104Sjkim (Type == ACPI_TYPE_PROCESSOR)) 431197104Sjkim { 432197104Sjkim /* 433197104Sjkim * Get extra info for ACPI Device/Processor objects only: 434197104Sjkim * Run the _STA, _ADR and, SxW, and _SxD methods. 435197104Sjkim * 436252279Sjkim * Notes: none of these methods are required, so they may or may 437197104Sjkim * not be present for this device. The Info->Valid bitfield is used 438197104Sjkim * to indicate which methods were found and run successfully. 439252279Sjkim * 440252279Sjkim * For _STA, if the method does not exist, then (as per the ACPI 441252279Sjkim * specification), the returned CurrentStatus flags will indicate 442252279Sjkim * that the device is present/functional/enabled. Otherwise, the 443252279Sjkim * CurrentStatus flags reflect the value returned from _STA. 444197104Sjkim */ 445197104Sjkim 446117521Snjl /* Execute the Device._STA method */ 447117521Snjl 448151937Sjkim Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus); 449117521Snjl if (ACPI_SUCCESS (Status)) 450117521Snjl { 451197104Sjkim Valid |= ACPI_VALID_STA; 452117521Snjl } 453117521Snjl 454117521Snjl /* Execute the Device._ADR method */ 455117521Snjl 456123315Snjl Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, 457306536Sjkim &Info->Address); 458117521Snjl if (ACPI_SUCCESS (Status)) 459117521Snjl { 460197104Sjkim Valid |= ACPI_VALID_ADR; 461117521Snjl } 462117521Snjl 463197104Sjkim /* Execute the Device._SxW methods */ 464197104Sjkim 465197104Sjkim Status = AcpiUtExecutePowerMethods (Node, 466306536Sjkim AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS, 467306536Sjkim Info->LowestDstates); 468197104Sjkim if (ACPI_SUCCESS (Status)) 469197104Sjkim { 470197104Sjkim Valid |= ACPI_VALID_SXWS; 471197104Sjkim } 472197104Sjkim 473126372Snjl /* Execute the Device._SxD methods */ 474126372Snjl 475197104Sjkim Status = AcpiUtExecutePowerMethods (Node, 476306536Sjkim AcpiGbl_HighestDstateNames, ACPI_NUM_SxD_METHODS, 477306536Sjkim Info->HighestDstates); 478126372Snjl if (ACPI_SUCCESS (Status)) 479126372Snjl { 480197104Sjkim Valid |= ACPI_VALID_SXDS; 481126372Snjl } 48267754Smsmith } 48367754Smsmith 484197104Sjkim /* 485197104Sjkim * Create a pointer to the string area of the return buffer. 486197104Sjkim * Point to the end of the base ACPI_DEVICE_INFO structure. 487197104Sjkim */ 488197104Sjkim NextIdString = ACPI_CAST_PTR (char, Info->CompatibleIdList.Ids); 489197104Sjkim if (CidList) 490197104Sjkim { 491241973Sjkim /* Point past the CID PNP_DEVICE_ID array */ 49267754Smsmith 493241973Sjkim NextIdString += ((ACPI_SIZE) CidList->Count * sizeof (ACPI_PNP_DEVICE_ID)); 494197104Sjkim } 495197104Sjkim 496197104Sjkim /* 497306536Sjkim * Copy the HID, UID, and CIDs to the return buffer. The variable-length 498306536Sjkim * strings are copied to the reserved area at the end of the buffer. 499197104Sjkim * 500197104Sjkim * For HID and CID, check if the ID is a PCI Root Bridge. 501197104Sjkim */ 502197104Sjkim if (Hid) 50367754Smsmith { 504197104Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->HardwareId, 505197104Sjkim Hid, NextIdString); 506197104Sjkim 507197104Sjkim if (AcpiUtIsPciRootBridge (Hid->String)) 508197104Sjkim { 509197104Sjkim Info->Flags |= ACPI_PCI_ROOT_BRIDGE; 510197104Sjkim } 51167754Smsmith } 51267754Smsmith 513197104Sjkim if (Uid) 514197104Sjkim { 515197104Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->UniqueId, 516197104Sjkim Uid, NextIdString); 517197104Sjkim } 518117521Snjl 519117521Snjl if (CidList) 52067754Smsmith { 521197104Sjkim Info->CompatibleIdList.Count = CidList->Count; 522197104Sjkim Info->CompatibleIdList.ListSize = CidList->ListSize; 523197104Sjkim 524197104Sjkim /* Copy each CID */ 525197104Sjkim 526197104Sjkim for (i = 0; i < CidList->Count; i++) 527197104Sjkim { 528197104Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->CompatibleIdList.Ids[i], 529197104Sjkim &CidList->Ids[i], NextIdString); 530197104Sjkim 531197104Sjkim if (AcpiUtIsPciRootBridge (CidList->Ids[i].String)) 532197104Sjkim { 533197104Sjkim Info->Flags |= ACPI_PCI_ROOT_BRIDGE; 534197104Sjkim } 535197104Sjkim } 53667754Smsmith } 53767754Smsmith 538306536Sjkim if (Cls) 539306536Sjkim { 540306536Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->ClassCode, 541306536Sjkim Cls, NextIdString); 542306536Sjkim } 543306536Sjkim 544197104Sjkim /* Copy the fixed-length data */ 54567754Smsmith 546197104Sjkim Info->InfoSize = InfoSize; 547197104Sjkim Info->Type = Type; 548197104Sjkim Info->Name = Name; 549197104Sjkim Info->ParamCount = ParamCount; 550197104Sjkim Info->Valid = Valid; 551197104Sjkim 552197104Sjkim *ReturnBuffer = Info; 553197104Sjkim Status = AE_OK; 554197104Sjkim 555197104Sjkim 556117521SnjlCleanup: 557197104Sjkim if (Hid) 558197104Sjkim { 559197104Sjkim ACPI_FREE (Hid); 560197104Sjkim } 561197104Sjkim if (Uid) 562197104Sjkim { 563197104Sjkim ACPI_FREE (Uid); 564197104Sjkim } 565117521Snjl if (CidList) 56667754Smsmith { 567167802Sjkim ACPI_FREE (CidList); 56867754Smsmith } 569306536Sjkim if (Cls) 570306536Sjkim { 571306536Sjkim ACPI_FREE (Cls); 572306536Sjkim } 573117521Snjl return (Status); 57467754Smsmith} 57567754Smsmith 576167802SjkimACPI_EXPORT_SYMBOL (AcpiGetObjectInfo) 577167802Sjkim 578193267Sjkim 579193267Sjkim/****************************************************************************** 580193267Sjkim * 581193267Sjkim * FUNCTION: AcpiInstallMethod 582193267Sjkim * 583193267Sjkim * PARAMETERS: Buffer - An ACPI table containing one control method 584193267Sjkim * 585193267Sjkim * RETURN: Status 586193267Sjkim * 587193267Sjkim * DESCRIPTION: Install a control method into the namespace. If the method 588193267Sjkim * name already exists in the namespace, it is overwritten. The 589193267Sjkim * input buffer must contain a valid DSDT or SSDT containing a 590193267Sjkim * single control method. 591193267Sjkim * 592193267Sjkim ******************************************************************************/ 593193267Sjkim 594193267SjkimACPI_STATUS 595193267SjkimAcpiInstallMethod ( 596193267Sjkim UINT8 *Buffer) 597193267Sjkim{ 598193267Sjkim ACPI_TABLE_HEADER *Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Buffer); 599193267Sjkim UINT8 *AmlBuffer; 600193267Sjkim UINT8 *AmlStart; 601193267Sjkim char *Path; 602193267Sjkim ACPI_NAMESPACE_NODE *Node; 603193267Sjkim ACPI_OPERAND_OBJECT *MethodObj; 604193267Sjkim ACPI_PARSE_STATE ParserState; 605193267Sjkim UINT32 AmlLength; 606193267Sjkim UINT16 Opcode; 607193267Sjkim UINT8 MethodFlags; 608193267Sjkim ACPI_STATUS Status; 609193267Sjkim 610193267Sjkim 611193267Sjkim /* Parameter validation */ 612193267Sjkim 613193267Sjkim if (!Buffer) 614193267Sjkim { 615193267Sjkim return (AE_BAD_PARAMETER); 616193267Sjkim } 617193267Sjkim 618193267Sjkim /* Table must be a DSDT or SSDT */ 619193267Sjkim 620193267Sjkim if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) && 621193267Sjkim !ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT)) 622193267Sjkim { 623193267Sjkim return (AE_BAD_HEADER); 624193267Sjkim } 625193267Sjkim 626193267Sjkim /* First AML opcode in the table must be a control method */ 627193267Sjkim 628193267Sjkim ParserState.Aml = Buffer + sizeof (ACPI_TABLE_HEADER); 629193267Sjkim Opcode = AcpiPsPeekOpcode (&ParserState); 630193267Sjkim if (Opcode != AML_METHOD_OP) 631193267Sjkim { 632193267Sjkim return (AE_BAD_PARAMETER); 633193267Sjkim } 634193267Sjkim 635193267Sjkim /* Extract method information from the raw AML */ 636193267Sjkim 637193267Sjkim ParserState.Aml += AcpiPsGetOpcodeSize (Opcode); 638193267Sjkim ParserState.PkgEnd = AcpiPsGetNextPackageEnd (&ParserState); 639193267Sjkim Path = AcpiPsGetNextNamestring (&ParserState); 640306536Sjkim 641193267Sjkim MethodFlags = *ParserState.Aml++; 642193267Sjkim AmlStart = ParserState.Aml; 643193267Sjkim AmlLength = ACPI_PTR_DIFF (ParserState.PkgEnd, AmlStart); 644193267Sjkim 645193267Sjkim /* 646193267Sjkim * Allocate resources up-front. We don't want to have to delete a new 647193267Sjkim * node from the namespace if we cannot allocate memory. 648193267Sjkim */ 649193267Sjkim AmlBuffer = ACPI_ALLOCATE (AmlLength); 650193267Sjkim if (!AmlBuffer) 651193267Sjkim { 652193267Sjkim return (AE_NO_MEMORY); 653193267Sjkim } 654193267Sjkim 655193267Sjkim MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 656193267Sjkim if (!MethodObj) 657193267Sjkim { 658193267Sjkim ACPI_FREE (AmlBuffer); 659193267Sjkim return (AE_NO_MEMORY); 660193267Sjkim } 661193267Sjkim 662193267Sjkim /* Lock namespace for AcpiNsLookup, we may be creating a new node */ 663193267Sjkim 664193267Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 665193267Sjkim if (ACPI_FAILURE (Status)) 666193267Sjkim { 667193267Sjkim goto ErrorExit; 668193267Sjkim } 669193267Sjkim 670193267Sjkim /* The lookup either returns an existing node or creates a new one */ 671193267Sjkim 672193267Sjkim Status = AcpiNsLookup (NULL, Path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1, 673306536Sjkim ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, NULL, &Node); 674193267Sjkim 675193267Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 676193267Sjkim 677193267Sjkim if (ACPI_FAILURE (Status)) /* NsLookup */ 678193267Sjkim { 679193267Sjkim if (Status != AE_ALREADY_EXISTS) 680193267Sjkim { 681193267Sjkim goto ErrorExit; 682193267Sjkim } 683193267Sjkim 684193267Sjkim /* Node existed previously, make sure it is a method node */ 685193267Sjkim 686193267Sjkim if (Node->Type != ACPI_TYPE_METHOD) 687193267Sjkim { 688193267Sjkim Status = AE_TYPE; 689193267Sjkim goto ErrorExit; 690193267Sjkim } 691193267Sjkim } 692193267Sjkim 693193267Sjkim /* Copy the method AML to the local buffer */ 694193267Sjkim 695306536Sjkim memcpy (AmlBuffer, AmlStart, AmlLength); 696193267Sjkim 697193267Sjkim /* Initialize the method object with the new method's information */ 698193267Sjkim 699193267Sjkim MethodObj->Method.AmlStart = AmlBuffer; 700193267Sjkim MethodObj->Method.AmlLength = AmlLength; 701193267Sjkim 702193267Sjkim MethodObj->Method.ParamCount = (UINT8) 703193267Sjkim (MethodFlags & AML_METHOD_ARG_COUNT); 704193267Sjkim 705193267Sjkim if (MethodFlags & AML_METHOD_SERIALIZED) 706193267Sjkim { 707217365Sjkim MethodObj->Method.InfoFlags = ACPI_METHOD_SERIALIZED; 708217365Sjkim 709193267Sjkim MethodObj->Method.SyncLevel = (UINT8) 710193267Sjkim ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4); 711193267Sjkim } 712193267Sjkim 713193267Sjkim /* 714193267Sjkim * Now that it is complete, we can attach the new method object to 715193267Sjkim * the method Node (detaches/deletes any existing object) 716193267Sjkim */ 717217365Sjkim Status = AcpiNsAttachObject (Node, MethodObj, ACPI_TYPE_METHOD); 718193267Sjkim 719193267Sjkim /* 720193267Sjkim * Flag indicates AML buffer is dynamic, must be deleted later. 721193267Sjkim * Must be set only after attach above. 722193267Sjkim */ 723193267Sjkim Node->Flags |= ANOBJ_ALLOCATED_BUFFER; 724193267Sjkim 725193267Sjkim /* Remove local reference to the method object */ 726193267Sjkim 727193267Sjkim AcpiUtRemoveReference (MethodObj); 728193267Sjkim return (Status); 729193267Sjkim 730193267Sjkim 731193267SjkimErrorExit: 732193267Sjkim 733193267Sjkim ACPI_FREE (AmlBuffer); 734193267Sjkim ACPI_FREE (MethodObj); 735193267Sjkim return (Status); 736193267Sjkim} 737193267Sjkim 738193267SjkimACPI_EXPORT_SYMBOL (AcpiInstallMethod) 739