167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: nsxfname - Public interfaces to the ACPI subsystem 467754Smsmith * ACPI Namespace oriented interfaces 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 8217365Sjkim/* 9281075Sdim * Copyright (C) 2000 - 2015, 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 129167802Sjkim if (!ACPI_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; 180252279Sjkim 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 19667754Smsmith if (NameType == ACPI_FULL_PATHNAME) 19767754Smsmith { 19867754Smsmith /* Get the full pathname (From the namespace root) */ 19967754Smsmith 20091116Smsmith Status = AcpiNsHandleToPathname (Handle, Buffer); 20167754Smsmith return (Status); 20267754Smsmith } 20367754Smsmith 20467754Smsmith /* 20567754Smsmith * Wants the single segment ACPI name. 20691116Smsmith * Validate handle and convert to a namespace Node 20767754Smsmith */ 20891116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 20991116Smsmith if (ACPI_FAILURE (Status)) 21091116Smsmith { 21191116Smsmith return (Status); 21291116Smsmith } 21391116Smsmith 214200553Sjkim Node = AcpiNsValidateHandle (Handle); 21567754Smsmith if (!Node) 21667754Smsmith { 21767754Smsmith Status = AE_BAD_PARAMETER; 21867754Smsmith goto UnlockAndExit; 21967754Smsmith } 22067754Smsmith 22191116Smsmith /* Validate/Allocate/Clear caller buffer */ 22267754Smsmith 223114237Snjl Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH); 22491116Smsmith if (ACPI_FAILURE (Status)) 22567754Smsmith { 22667754Smsmith goto UnlockAndExit; 22767754Smsmith } 22867754Smsmith 22967754Smsmith /* Just copy the ACPI name from the Node and zero terminate it */ 23067754Smsmith 231252279Sjkim NodeName = AcpiUtGetNodeName (Node); 232252279Sjkim ACPI_MOVE_NAME (Buffer->Pointer, NodeName); 233114237Snjl ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0; 23467754Smsmith Status = AE_OK; 23567754Smsmith 23667754Smsmith 23767754SmsmithUnlockAndExit: 23867754Smsmith 23991116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 24067754Smsmith return (Status); 24167754Smsmith} 24267754Smsmith 243167802SjkimACPI_EXPORT_SYMBOL (AcpiGetName) 24467754Smsmith 245167802Sjkim 246117521Snjl/****************************************************************************** 24767754Smsmith * 248197104Sjkim * FUNCTION: AcpiNsCopyDeviceId 249197104Sjkim * 250241973Sjkim * PARAMETERS: Dest - Pointer to the destination PNP_DEVICE_ID 251241973Sjkim * Source - Pointer to the source PNP_DEVICE_ID 252197104Sjkim * StringArea - Pointer to where to copy the dest string 253197104Sjkim * 254197104Sjkim * RETURN: Pointer to the next string area 255197104Sjkim * 256241973Sjkim * DESCRIPTION: Copy a single PNP_DEVICE_ID, including the string data. 257197104Sjkim * 258197104Sjkim ******************************************************************************/ 259197104Sjkim 260197104Sjkimstatic char * 261197104SjkimAcpiNsCopyDeviceId ( 262241973Sjkim ACPI_PNP_DEVICE_ID *Dest, 263241973Sjkim ACPI_PNP_DEVICE_ID *Source, 264197104Sjkim char *StringArea) 265197104Sjkim{ 266197104Sjkim 267241973Sjkim /* Create the destination PNP_DEVICE_ID */ 268241973Sjkim 269197104Sjkim Dest->String = StringArea; 270197104Sjkim Dest->Length = Source->Length; 271197104Sjkim 272197104Sjkim /* Copy actual string and return a pointer to the next string area */ 273197104Sjkim 274197104Sjkim ACPI_MEMCPY (StringArea, Source->String, Source->Length); 275197104Sjkim return (StringArea + Source->Length); 276197104Sjkim} 277197104Sjkim 278197104Sjkim 279197104Sjkim/****************************************************************************** 280197104Sjkim * 28167754Smsmith * FUNCTION: AcpiGetObjectInfo 28267754Smsmith * 283197104Sjkim * PARAMETERS: Handle - Object Handle 284197104Sjkim * ReturnBuffer - Where the info is returned 28567754Smsmith * 28667754Smsmith * RETURN: Status 28767754Smsmith * 28867754Smsmith * DESCRIPTION: Returns information about an object as gleaned from the 28967754Smsmith * namespace node and possibly by running several standard 29067754Smsmith * control methods (Such as in the case of a device.) 29167754Smsmith * 292241973Sjkim * For Device and Processor objects, run the Device _HID, _UID, _CID, _SUB, 293241973Sjkim * _STA, _ADR, _SxW, and _SxD methods. 294197104Sjkim * 295197104Sjkim * Note: Allocates the return buffer, must be freed by the caller. 296197104Sjkim * 29767754Smsmith ******************************************************************************/ 29867754Smsmith 29967754SmsmithACPI_STATUS 30067754SmsmithAcpiGetObjectInfo ( 30167754Smsmith ACPI_HANDLE Handle, 302197104Sjkim ACPI_DEVICE_INFO **ReturnBuffer) 30367754Smsmith{ 30467754Smsmith ACPI_NAMESPACE_NODE *Node; 305151937Sjkim ACPI_DEVICE_INFO *Info; 306241973Sjkim ACPI_PNP_DEVICE_ID_LIST *CidList = NULL; 307241973Sjkim ACPI_PNP_DEVICE_ID *Hid = NULL; 308241973Sjkim ACPI_PNP_DEVICE_ID *Uid = NULL; 309241973Sjkim ACPI_PNP_DEVICE_ID *Sub = NULL; 310197104Sjkim char *NextIdString; 311197104Sjkim ACPI_OBJECT_TYPE Type; 312197104Sjkim ACPI_NAME Name; 313197104Sjkim UINT8 ParamCount= 0; 314197104Sjkim UINT8 Valid = 0; 315197104Sjkim UINT32 InfoSize; 316197104Sjkim UINT32 i; 317197104Sjkim ACPI_STATUS Status; 31867754Smsmith 31967754Smsmith 32067754Smsmith /* Parameter validation */ 32167754Smsmith 322197104Sjkim if (!Handle || !ReturnBuffer) 32367754Smsmith { 32467754Smsmith return (AE_BAD_PARAMETER); 32567754Smsmith } 32667754Smsmith 32791116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 32891116Smsmith if (ACPI_FAILURE (Status)) 32991116Smsmith { 330243347Sjkim return (Status); 33191116Smsmith } 33267754Smsmith 333200553Sjkim Node = AcpiNsValidateHandle (Handle); 33467754Smsmith if (!Node) 33567754Smsmith { 33691116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 337197104Sjkim return (AE_BAD_PARAMETER); 33867754Smsmith } 33967754Smsmith 340197104Sjkim /* Get the namespace node data while the namespace is locked */ 34167754Smsmith 342197104Sjkim InfoSize = sizeof (ACPI_DEVICE_INFO); 343197104Sjkim Type = Node->Type; 344197104Sjkim Name = Node->Name.Integer; 345117521Snjl 346193267Sjkim if (Node->Type == ACPI_TYPE_METHOD) 347193267Sjkim { 348197104Sjkim ParamCount = Node->Object->Method.ParamCount; 349193267Sjkim } 350193267Sjkim 35191116Smsmith Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 35291116Smsmith if (ACPI_FAILURE (Status)) 35391116Smsmith { 354197104Sjkim return (Status); 35591116Smsmith } 35667754Smsmith 357197104Sjkim if ((Type == ACPI_TYPE_DEVICE) || 358197104Sjkim (Type == ACPI_TYPE_PROCESSOR)) 35967754Smsmith { 360117521Snjl /* 361197104Sjkim * Get extra info for ACPI Device/Processor objects only: 362241973Sjkim * Run the Device _HID, _UID, _SUB, and _CID methods. 363123315Snjl * 364117521Snjl * Note: none of these methods are required, so they may or may 365197104Sjkim * not be present for this device. The Info->Valid bitfield is used 366197104Sjkim * to indicate which methods were found and run successfully. 367117521Snjl */ 36867754Smsmith 369117521Snjl /* Execute the Device._HID method */ 37067754Smsmith 371197104Sjkim Status = AcpiUtExecute_HID (Node, &Hid); 372117521Snjl if (ACPI_SUCCESS (Status)) 373117521Snjl { 374197104Sjkim InfoSize += Hid->Length; 375197104Sjkim Valid |= ACPI_VALID_HID; 376117521Snjl } 37767754Smsmith 378117521Snjl /* Execute the Device._UID method */ 37967754Smsmith 380197104Sjkim Status = AcpiUtExecute_UID (Node, &Uid); 381117521Snjl if (ACPI_SUCCESS (Status)) 382117521Snjl { 383197104Sjkim InfoSize += Uid->Length; 384197104Sjkim Valid |= ACPI_VALID_UID; 385117521Snjl } 386117521Snjl 387241973Sjkim /* Execute the Device._SUB method */ 388241973Sjkim 389241973Sjkim Status = AcpiUtExecute_SUB (Node, &Sub); 390241973Sjkim if (ACPI_SUCCESS (Status)) 391241973Sjkim { 392241973Sjkim InfoSize += Sub->Length; 393241973Sjkim Valid |= ACPI_VALID_SUB; 394241973Sjkim } 395241973Sjkim 396117521Snjl /* Execute the Device._CID method */ 397117521Snjl 398117521Snjl Status = AcpiUtExecute_CID (Node, &CidList); 399117521Snjl if (ACPI_SUCCESS (Status)) 400117521Snjl { 401197104Sjkim /* Add size of CID strings and CID pointer array */ 402197104Sjkim 403241973Sjkim InfoSize += (CidList->ListSize - sizeof (ACPI_PNP_DEVICE_ID_LIST)); 404197104Sjkim Valid |= ACPI_VALID_CID; 405117521Snjl } 406197104Sjkim } 407117521Snjl 408197104Sjkim /* 409197104Sjkim * Now that we have the variable-length data, we can allocate the 410197104Sjkim * return buffer 411197104Sjkim */ 412197104Sjkim Info = ACPI_ALLOCATE_ZEROED (InfoSize); 413197104Sjkim if (!Info) 414197104Sjkim { 415197104Sjkim Status = AE_NO_MEMORY; 416197104Sjkim goto Cleanup; 417197104Sjkim } 418197104Sjkim 419197104Sjkim /* Get the fixed-length data */ 420197104Sjkim 421197104Sjkim if ((Type == ACPI_TYPE_DEVICE) || 422197104Sjkim (Type == ACPI_TYPE_PROCESSOR)) 423197104Sjkim { 424197104Sjkim /* 425197104Sjkim * Get extra info for ACPI Device/Processor objects only: 426197104Sjkim * Run the _STA, _ADR and, SxW, and _SxD methods. 427197104Sjkim * 428252279Sjkim * Notes: none of these methods are required, so they may or may 429197104Sjkim * not be present for this device. The Info->Valid bitfield is used 430197104Sjkim * to indicate which methods were found and run successfully. 431252279Sjkim * 432252279Sjkim * For _STA, if the method does not exist, then (as per the ACPI 433252279Sjkim * specification), the returned CurrentStatus flags will indicate 434252279Sjkim * that the device is present/functional/enabled. Otherwise, the 435252279Sjkim * CurrentStatus flags reflect the value returned from _STA. 436197104Sjkim */ 437197104Sjkim 438117521Snjl /* Execute the Device._STA method */ 439117521Snjl 440151937Sjkim Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus); 441117521Snjl if (ACPI_SUCCESS (Status)) 442117521Snjl { 443197104Sjkim Valid |= ACPI_VALID_STA; 444117521Snjl } 445117521Snjl 446117521Snjl /* Execute the Device._ADR method */ 447117521Snjl 448123315Snjl Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, 449197104Sjkim &Info->Address); 450117521Snjl if (ACPI_SUCCESS (Status)) 451117521Snjl { 452197104Sjkim Valid |= ACPI_VALID_ADR; 453117521Snjl } 454117521Snjl 455197104Sjkim /* Execute the Device._SxW methods */ 456197104Sjkim 457197104Sjkim Status = AcpiUtExecutePowerMethods (Node, 458197104Sjkim AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS, 459197104Sjkim Info->LowestDstates); 460197104Sjkim if (ACPI_SUCCESS (Status)) 461197104Sjkim { 462197104Sjkim Valid |= ACPI_VALID_SXWS; 463197104Sjkim } 464197104Sjkim 465126372Snjl /* Execute the Device._SxD methods */ 466126372Snjl 467197104Sjkim Status = AcpiUtExecutePowerMethods (Node, 468197104Sjkim AcpiGbl_HighestDstateNames, ACPI_NUM_SxD_METHODS, 469197104Sjkim Info->HighestDstates); 470126372Snjl if (ACPI_SUCCESS (Status)) 471126372Snjl { 472197104Sjkim Valid |= ACPI_VALID_SXDS; 473126372Snjl } 47467754Smsmith } 47567754Smsmith 476197104Sjkim /* 477197104Sjkim * Create a pointer to the string area of the return buffer. 478197104Sjkim * Point to the end of the base ACPI_DEVICE_INFO structure. 479197104Sjkim */ 480197104Sjkim NextIdString = ACPI_CAST_PTR (char, Info->CompatibleIdList.Ids); 481197104Sjkim if (CidList) 482197104Sjkim { 483241973Sjkim /* Point past the CID PNP_DEVICE_ID array */ 48467754Smsmith 485241973Sjkim NextIdString += ((ACPI_SIZE) CidList->Count * sizeof (ACPI_PNP_DEVICE_ID)); 486197104Sjkim } 487197104Sjkim 488197104Sjkim /* 489241973Sjkim * Copy the HID, UID, SUB, and CIDs to the return buffer. 490241973Sjkim * The variable-length strings are copied to the reserved area 491241973Sjkim * at the end of the buffer. 492197104Sjkim * 493197104Sjkim * For HID and CID, check if the ID is a PCI Root Bridge. 494197104Sjkim */ 495197104Sjkim if (Hid) 49667754Smsmith { 497197104Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->HardwareId, 498197104Sjkim Hid, NextIdString); 499197104Sjkim 500197104Sjkim if (AcpiUtIsPciRootBridge (Hid->String)) 501197104Sjkim { 502197104Sjkim Info->Flags |= ACPI_PCI_ROOT_BRIDGE; 503197104Sjkim } 50467754Smsmith } 50567754Smsmith 506197104Sjkim if (Uid) 507197104Sjkim { 508197104Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->UniqueId, 509197104Sjkim Uid, NextIdString); 510197104Sjkim } 511117521Snjl 512241973Sjkim if (Sub) 513241973Sjkim { 514241973Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->SubsystemId, 515241973Sjkim Sub, NextIdString); 516241973Sjkim } 517241973Sjkim 518117521Snjl if (CidList) 51967754Smsmith { 520197104Sjkim Info->CompatibleIdList.Count = CidList->Count; 521197104Sjkim Info->CompatibleIdList.ListSize = CidList->ListSize; 522197104Sjkim 523197104Sjkim /* Copy each CID */ 524197104Sjkim 525197104Sjkim for (i = 0; i < CidList->Count; i++) 526197104Sjkim { 527197104Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->CompatibleIdList.Ids[i], 528197104Sjkim &CidList->Ids[i], NextIdString); 529197104Sjkim 530197104Sjkim if (AcpiUtIsPciRootBridge (CidList->Ids[i].String)) 531197104Sjkim { 532197104Sjkim Info->Flags |= ACPI_PCI_ROOT_BRIDGE; 533197104Sjkim } 534197104Sjkim } 53567754Smsmith } 53667754Smsmith 537197104Sjkim /* Copy the fixed-length data */ 53867754Smsmith 539197104Sjkim Info->InfoSize = InfoSize; 540197104Sjkim Info->Type = Type; 541197104Sjkim Info->Name = Name; 542197104Sjkim Info->ParamCount = ParamCount; 543197104Sjkim Info->Valid = Valid; 544197104Sjkim 545197104Sjkim *ReturnBuffer = Info; 546197104Sjkim Status = AE_OK; 547197104Sjkim 548197104Sjkim 549117521SnjlCleanup: 550197104Sjkim if (Hid) 551197104Sjkim { 552197104Sjkim ACPI_FREE (Hid); 553197104Sjkim } 554197104Sjkim if (Uid) 555197104Sjkim { 556197104Sjkim ACPI_FREE (Uid); 557197104Sjkim } 558241973Sjkim if (Sub) 559241973Sjkim { 560241973Sjkim ACPI_FREE (Sub); 561241973Sjkim } 562117521Snjl if (CidList) 56367754Smsmith { 564167802Sjkim ACPI_FREE (CidList); 56567754Smsmith } 566117521Snjl return (Status); 56767754Smsmith} 56867754Smsmith 569167802SjkimACPI_EXPORT_SYMBOL (AcpiGetObjectInfo) 570167802Sjkim 571193267Sjkim 572193267Sjkim/****************************************************************************** 573193267Sjkim * 574193267Sjkim * FUNCTION: AcpiInstallMethod 575193267Sjkim * 576193267Sjkim * PARAMETERS: Buffer - An ACPI table containing one control method 577193267Sjkim * 578193267Sjkim * RETURN: Status 579193267Sjkim * 580193267Sjkim * DESCRIPTION: Install a control method into the namespace. If the method 581193267Sjkim * name already exists in the namespace, it is overwritten. The 582193267Sjkim * input buffer must contain a valid DSDT or SSDT containing a 583193267Sjkim * single control method. 584193267Sjkim * 585193267Sjkim ******************************************************************************/ 586193267Sjkim 587193267SjkimACPI_STATUS 588193267SjkimAcpiInstallMethod ( 589193267Sjkim UINT8 *Buffer) 590193267Sjkim{ 591193267Sjkim ACPI_TABLE_HEADER *Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Buffer); 592193267Sjkim UINT8 *AmlBuffer; 593193267Sjkim UINT8 *AmlStart; 594193267Sjkim char *Path; 595193267Sjkim ACPI_NAMESPACE_NODE *Node; 596193267Sjkim ACPI_OPERAND_OBJECT *MethodObj; 597193267Sjkim ACPI_PARSE_STATE ParserState; 598193267Sjkim UINT32 AmlLength; 599193267Sjkim UINT16 Opcode; 600193267Sjkim UINT8 MethodFlags; 601193267Sjkim ACPI_STATUS Status; 602193267Sjkim 603193267Sjkim 604193267Sjkim /* Parameter validation */ 605193267Sjkim 606193267Sjkim if (!Buffer) 607193267Sjkim { 608193267Sjkim return (AE_BAD_PARAMETER); 609193267Sjkim } 610193267Sjkim 611193267Sjkim /* Table must be a DSDT or SSDT */ 612193267Sjkim 613193267Sjkim if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) && 614193267Sjkim !ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT)) 615193267Sjkim { 616193267Sjkim return (AE_BAD_HEADER); 617193267Sjkim } 618193267Sjkim 619193267Sjkim /* First AML opcode in the table must be a control method */ 620193267Sjkim 621193267Sjkim ParserState.Aml = Buffer + sizeof (ACPI_TABLE_HEADER); 622193267Sjkim Opcode = AcpiPsPeekOpcode (&ParserState); 623193267Sjkim if (Opcode != AML_METHOD_OP) 624193267Sjkim { 625193267Sjkim return (AE_BAD_PARAMETER); 626193267Sjkim } 627193267Sjkim 628193267Sjkim /* Extract method information from the raw AML */ 629193267Sjkim 630193267Sjkim ParserState.Aml += AcpiPsGetOpcodeSize (Opcode); 631193267Sjkim ParserState.PkgEnd = AcpiPsGetNextPackageEnd (&ParserState); 632193267Sjkim Path = AcpiPsGetNextNamestring (&ParserState); 633193267Sjkim MethodFlags = *ParserState.Aml++; 634193267Sjkim AmlStart = ParserState.Aml; 635193267Sjkim AmlLength = ACPI_PTR_DIFF (ParserState.PkgEnd, AmlStart); 636193267Sjkim 637193267Sjkim /* 638193267Sjkim * Allocate resources up-front. We don't want to have to delete a new 639193267Sjkim * node from the namespace if we cannot allocate memory. 640193267Sjkim */ 641193267Sjkim AmlBuffer = ACPI_ALLOCATE (AmlLength); 642193267Sjkim if (!AmlBuffer) 643193267Sjkim { 644193267Sjkim return (AE_NO_MEMORY); 645193267Sjkim } 646193267Sjkim 647193267Sjkim MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 648193267Sjkim if (!MethodObj) 649193267Sjkim { 650193267Sjkim ACPI_FREE (AmlBuffer); 651193267Sjkim return (AE_NO_MEMORY); 652193267Sjkim } 653193267Sjkim 654193267Sjkim /* Lock namespace for AcpiNsLookup, we may be creating a new node */ 655193267Sjkim 656193267Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 657193267Sjkim if (ACPI_FAILURE (Status)) 658193267Sjkim { 659193267Sjkim goto ErrorExit; 660193267Sjkim } 661193267Sjkim 662193267Sjkim /* The lookup either returns an existing node or creates a new one */ 663193267Sjkim 664193267Sjkim Status = AcpiNsLookup (NULL, Path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1, 665193267Sjkim ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, NULL, &Node); 666193267Sjkim 667193267Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 668193267Sjkim 669193267Sjkim if (ACPI_FAILURE (Status)) /* NsLookup */ 670193267Sjkim { 671193267Sjkim if (Status != AE_ALREADY_EXISTS) 672193267Sjkim { 673193267Sjkim goto ErrorExit; 674193267Sjkim } 675193267Sjkim 676193267Sjkim /* Node existed previously, make sure it is a method node */ 677193267Sjkim 678193267Sjkim if (Node->Type != ACPI_TYPE_METHOD) 679193267Sjkim { 680193267Sjkim Status = AE_TYPE; 681193267Sjkim goto ErrorExit; 682193267Sjkim } 683193267Sjkim } 684193267Sjkim 685193267Sjkim /* Copy the method AML to the local buffer */ 686193267Sjkim 687193267Sjkim ACPI_MEMCPY (AmlBuffer, AmlStart, AmlLength); 688193267Sjkim 689193267Sjkim /* Initialize the method object with the new method's information */ 690193267Sjkim 691193267Sjkim MethodObj->Method.AmlStart = AmlBuffer; 692193267Sjkim MethodObj->Method.AmlLength = AmlLength; 693193267Sjkim 694193267Sjkim MethodObj->Method.ParamCount = (UINT8) 695193267Sjkim (MethodFlags & AML_METHOD_ARG_COUNT); 696193267Sjkim 697193267Sjkim if (MethodFlags & AML_METHOD_SERIALIZED) 698193267Sjkim { 699217365Sjkim MethodObj->Method.InfoFlags = ACPI_METHOD_SERIALIZED; 700217365Sjkim 701193267Sjkim MethodObj->Method.SyncLevel = (UINT8) 702193267Sjkim ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4); 703193267Sjkim } 704193267Sjkim 705193267Sjkim /* 706193267Sjkim * Now that it is complete, we can attach the new method object to 707193267Sjkim * the method Node (detaches/deletes any existing object) 708193267Sjkim */ 709217365Sjkim Status = AcpiNsAttachObject (Node, MethodObj, ACPI_TYPE_METHOD); 710193267Sjkim 711193267Sjkim /* 712193267Sjkim * Flag indicates AML buffer is dynamic, must be deleted later. 713193267Sjkim * Must be set only after attach above. 714193267Sjkim */ 715193267Sjkim Node->Flags |= ANOBJ_ALLOCATED_BUFFER; 716193267Sjkim 717193267Sjkim /* Remove local reference to the method object */ 718193267Sjkim 719193267Sjkim AcpiUtRemoveReference (MethodObj); 720193267Sjkim return (Status); 721193267Sjkim 722193267Sjkim 723193267SjkimErrorExit: 724193267Sjkim 725193267Sjkim ACPI_FREE (AmlBuffer); 726193267Sjkim ACPI_FREE (MethodObj); 727193267Sjkim return (Status); 728193267Sjkim} 729193267Sjkim 730193267SjkimACPI_EXPORT_SYMBOL (AcpiInstallMethod) 731