nsxfname.c revision 243347
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: nsxfname - Public interfaces to the ACPI subsystem 467754Smsmith * ACPI Namespace oriented interfaces 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 8217365Sjkim/* 9229989Sjkim * Copyright (C) 2000 - 2012, 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#define __NSXFNAME_C__ 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 */ 123167802Sjkim if (AcpiNsValidRootPrefix (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; 18067754Smsmith 18167754Smsmith 18291116Smsmith /* Parameter validation */ 18367754Smsmith 18491116Smsmith if (NameType > ACPI_NAME_TYPE_MAX) 18567754Smsmith { 18667754Smsmith return (AE_BAD_PARAMETER); 18767754Smsmith } 18867754Smsmith 18991116Smsmith Status = AcpiUtValidateBuffer (Buffer); 19091116Smsmith if (ACPI_FAILURE (Status)) 19167754Smsmith { 19291116Smsmith return (Status); 19367754Smsmith } 19467754Smsmith 19567754Smsmith if (NameType == ACPI_FULL_PATHNAME) 19667754Smsmith { 19767754Smsmith /* Get the full pathname (From the namespace root) */ 19867754Smsmith 19991116Smsmith Status = AcpiNsHandleToPathname (Handle, Buffer); 20067754Smsmith return (Status); 20167754Smsmith } 20267754Smsmith 20367754Smsmith /* 20467754Smsmith * Wants the single segment ACPI name. 20591116Smsmith * Validate handle and convert to a namespace Node 20667754Smsmith */ 20791116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 20891116Smsmith if (ACPI_FAILURE (Status)) 20991116Smsmith { 21091116Smsmith return (Status); 21191116Smsmith } 21291116Smsmith 213200553Sjkim Node = AcpiNsValidateHandle (Handle); 21467754Smsmith if (!Node) 21567754Smsmith { 21667754Smsmith Status = AE_BAD_PARAMETER; 21767754Smsmith goto UnlockAndExit; 21867754Smsmith } 21967754Smsmith 22091116Smsmith /* Validate/Allocate/Clear caller buffer */ 22167754Smsmith 222114237Snjl Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH); 22391116Smsmith if (ACPI_FAILURE (Status)) 22467754Smsmith { 22567754Smsmith goto UnlockAndExit; 22667754Smsmith } 22767754Smsmith 22867754Smsmith /* Just copy the ACPI name from the Node and zero terminate it */ 22967754Smsmith 230241973Sjkim ACPI_MOVE_NAME (Buffer->Pointer, AcpiUtGetNodeName (Node)); 231114237Snjl ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0; 23267754Smsmith Status = AE_OK; 23367754Smsmith 23467754Smsmith 23567754SmsmithUnlockAndExit: 23667754Smsmith 23791116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 23867754Smsmith return (Status); 23967754Smsmith} 24067754Smsmith 241167802SjkimACPI_EXPORT_SYMBOL (AcpiGetName) 24267754Smsmith 243167802Sjkim 244117521Snjl/****************************************************************************** 24567754Smsmith * 246197104Sjkim * FUNCTION: AcpiNsCopyDeviceId 247197104Sjkim * 248241973Sjkim * PARAMETERS: Dest - Pointer to the destination PNP_DEVICE_ID 249241973Sjkim * Source - Pointer to the source PNP_DEVICE_ID 250197104Sjkim * StringArea - Pointer to where to copy the dest string 251197104Sjkim * 252197104Sjkim * RETURN: Pointer to the next string area 253197104Sjkim * 254241973Sjkim * DESCRIPTION: Copy a single PNP_DEVICE_ID, including the string data. 255197104Sjkim * 256197104Sjkim ******************************************************************************/ 257197104Sjkim 258197104Sjkimstatic char * 259197104SjkimAcpiNsCopyDeviceId ( 260241973Sjkim ACPI_PNP_DEVICE_ID *Dest, 261241973Sjkim ACPI_PNP_DEVICE_ID *Source, 262197104Sjkim char *StringArea) 263197104Sjkim{ 264197104Sjkim 265241973Sjkim /* Create the destination PNP_DEVICE_ID */ 266241973Sjkim 267197104Sjkim Dest->String = StringArea; 268197104Sjkim Dest->Length = Source->Length; 269197104Sjkim 270197104Sjkim /* Copy actual string and return a pointer to the next string area */ 271197104Sjkim 272197104Sjkim ACPI_MEMCPY (StringArea, Source->String, Source->Length); 273197104Sjkim return (StringArea + Source->Length); 274197104Sjkim} 275197104Sjkim 276197104Sjkim 277197104Sjkim/****************************************************************************** 278197104Sjkim * 27967754Smsmith * FUNCTION: AcpiGetObjectInfo 28067754Smsmith * 281197104Sjkim * PARAMETERS: Handle - Object Handle 282197104Sjkim * ReturnBuffer - Where the info is returned 28367754Smsmith * 28467754Smsmith * RETURN: Status 28567754Smsmith * 28667754Smsmith * DESCRIPTION: Returns information about an object as gleaned from the 28767754Smsmith * namespace node and possibly by running several standard 28867754Smsmith * control methods (Such as in the case of a device.) 28967754Smsmith * 290241973Sjkim * For Device and Processor objects, run the Device _HID, _UID, _CID, _SUB, 291241973Sjkim * _STA, _ADR, _SxW, and _SxD methods. 292197104Sjkim * 293197104Sjkim * Note: Allocates the return buffer, must be freed by the caller. 294197104Sjkim * 29567754Smsmith ******************************************************************************/ 29667754Smsmith 29767754SmsmithACPI_STATUS 29867754SmsmithAcpiGetObjectInfo ( 29967754Smsmith ACPI_HANDLE Handle, 300197104Sjkim ACPI_DEVICE_INFO **ReturnBuffer) 30167754Smsmith{ 30267754Smsmith ACPI_NAMESPACE_NODE *Node; 303151937Sjkim ACPI_DEVICE_INFO *Info; 304241973Sjkim ACPI_PNP_DEVICE_ID_LIST *CidList = NULL; 305241973Sjkim ACPI_PNP_DEVICE_ID *Hid = NULL; 306241973Sjkim ACPI_PNP_DEVICE_ID *Uid = NULL; 307241973Sjkim ACPI_PNP_DEVICE_ID *Sub = NULL; 308197104Sjkim char *NextIdString; 309197104Sjkim ACPI_OBJECT_TYPE Type; 310197104Sjkim ACPI_NAME Name; 311197104Sjkim UINT8 ParamCount= 0; 312197104Sjkim UINT8 Valid = 0; 313197104Sjkim UINT32 InfoSize; 314197104Sjkim UINT32 i; 315197104Sjkim ACPI_STATUS Status; 31667754Smsmith 31767754Smsmith 31867754Smsmith /* Parameter validation */ 31967754Smsmith 320197104Sjkim if (!Handle || !ReturnBuffer) 32167754Smsmith { 32267754Smsmith return (AE_BAD_PARAMETER); 32367754Smsmith } 32467754Smsmith 32591116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 32691116Smsmith if (ACPI_FAILURE (Status)) 32791116Smsmith { 328243347Sjkim return (Status); 32991116Smsmith } 33067754Smsmith 331200553Sjkim Node = AcpiNsValidateHandle (Handle); 33267754Smsmith if (!Node) 33367754Smsmith { 33491116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 335197104Sjkim return (AE_BAD_PARAMETER); 33667754Smsmith } 33767754Smsmith 338197104Sjkim /* Get the namespace node data while the namespace is locked */ 33967754Smsmith 340197104Sjkim InfoSize = sizeof (ACPI_DEVICE_INFO); 341197104Sjkim Type = Node->Type; 342197104Sjkim Name = Node->Name.Integer; 343117521Snjl 344193267Sjkim if (Node->Type == ACPI_TYPE_METHOD) 345193267Sjkim { 346197104Sjkim ParamCount = Node->Object->Method.ParamCount; 347193267Sjkim } 348193267Sjkim 34991116Smsmith Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 35091116Smsmith if (ACPI_FAILURE (Status)) 35191116Smsmith { 352197104Sjkim return (Status); 35391116Smsmith } 35467754Smsmith 355197104Sjkim if ((Type == ACPI_TYPE_DEVICE) || 356197104Sjkim (Type == ACPI_TYPE_PROCESSOR)) 35767754Smsmith { 358117521Snjl /* 359197104Sjkim * Get extra info for ACPI Device/Processor objects only: 360241973Sjkim * Run the Device _HID, _UID, _SUB, and _CID methods. 361123315Snjl * 362117521Snjl * Note: none of these methods are required, so they may or may 363197104Sjkim * not be present for this device. The Info->Valid bitfield is used 364197104Sjkim * to indicate which methods were found and run successfully. 365117521Snjl */ 36667754Smsmith 367117521Snjl /* Execute the Device._HID method */ 36867754Smsmith 369197104Sjkim Status = AcpiUtExecute_HID (Node, &Hid); 370117521Snjl if (ACPI_SUCCESS (Status)) 371117521Snjl { 372197104Sjkim InfoSize += Hid->Length; 373197104Sjkim Valid |= ACPI_VALID_HID; 374117521Snjl } 37567754Smsmith 376117521Snjl /* Execute the Device._UID method */ 37767754Smsmith 378197104Sjkim Status = AcpiUtExecute_UID (Node, &Uid); 379117521Snjl if (ACPI_SUCCESS (Status)) 380117521Snjl { 381197104Sjkim InfoSize += Uid->Length; 382197104Sjkim Valid |= ACPI_VALID_UID; 383117521Snjl } 384117521Snjl 385241973Sjkim /* Execute the Device._SUB method */ 386241973Sjkim 387241973Sjkim Status = AcpiUtExecute_SUB (Node, &Sub); 388241973Sjkim if (ACPI_SUCCESS (Status)) 389241973Sjkim { 390241973Sjkim InfoSize += Sub->Length; 391241973Sjkim Valid |= ACPI_VALID_SUB; 392241973Sjkim } 393241973Sjkim 394117521Snjl /* Execute the Device._CID method */ 395117521Snjl 396117521Snjl Status = AcpiUtExecute_CID (Node, &CidList); 397117521Snjl if (ACPI_SUCCESS (Status)) 398117521Snjl { 399197104Sjkim /* Add size of CID strings and CID pointer array */ 400197104Sjkim 401241973Sjkim InfoSize += (CidList->ListSize - sizeof (ACPI_PNP_DEVICE_ID_LIST)); 402197104Sjkim Valid |= ACPI_VALID_CID; 403117521Snjl } 404197104Sjkim } 405117521Snjl 406197104Sjkim /* 407197104Sjkim * Now that we have the variable-length data, we can allocate the 408197104Sjkim * return buffer 409197104Sjkim */ 410197104Sjkim Info = ACPI_ALLOCATE_ZEROED (InfoSize); 411197104Sjkim if (!Info) 412197104Sjkim { 413197104Sjkim Status = AE_NO_MEMORY; 414197104Sjkim goto Cleanup; 415197104Sjkim } 416197104Sjkim 417197104Sjkim /* Get the fixed-length data */ 418197104Sjkim 419197104Sjkim if ((Type == ACPI_TYPE_DEVICE) || 420197104Sjkim (Type == ACPI_TYPE_PROCESSOR)) 421197104Sjkim { 422197104Sjkim /* 423197104Sjkim * Get extra info for ACPI Device/Processor objects only: 424197104Sjkim * Run the _STA, _ADR and, SxW, and _SxD methods. 425197104Sjkim * 426197104Sjkim * Note: none of these methods are required, so they may or may 427197104Sjkim * not be present for this device. The Info->Valid bitfield is used 428197104Sjkim * to indicate which methods were found and run successfully. 429197104Sjkim */ 430197104Sjkim 431117521Snjl /* Execute the Device._STA method */ 432117521Snjl 433151937Sjkim Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus); 434117521Snjl if (ACPI_SUCCESS (Status)) 435117521Snjl { 436197104Sjkim Valid |= ACPI_VALID_STA; 437117521Snjl } 438117521Snjl 439117521Snjl /* Execute the Device._ADR method */ 440117521Snjl 441123315Snjl Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, 442197104Sjkim &Info->Address); 443117521Snjl if (ACPI_SUCCESS (Status)) 444117521Snjl { 445197104Sjkim Valid |= ACPI_VALID_ADR; 446117521Snjl } 447117521Snjl 448197104Sjkim /* Execute the Device._SxW methods */ 449197104Sjkim 450197104Sjkim Status = AcpiUtExecutePowerMethods (Node, 451197104Sjkim AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS, 452197104Sjkim Info->LowestDstates); 453197104Sjkim if (ACPI_SUCCESS (Status)) 454197104Sjkim { 455197104Sjkim Valid |= ACPI_VALID_SXWS; 456197104Sjkim } 457197104Sjkim 458126372Snjl /* Execute the Device._SxD methods */ 459126372Snjl 460197104Sjkim Status = AcpiUtExecutePowerMethods (Node, 461197104Sjkim AcpiGbl_HighestDstateNames, ACPI_NUM_SxD_METHODS, 462197104Sjkim Info->HighestDstates); 463126372Snjl if (ACPI_SUCCESS (Status)) 464126372Snjl { 465197104Sjkim Valid |= ACPI_VALID_SXDS; 466126372Snjl } 46767754Smsmith } 46867754Smsmith 469197104Sjkim /* 470197104Sjkim * Create a pointer to the string area of the return buffer. 471197104Sjkim * Point to the end of the base ACPI_DEVICE_INFO structure. 472197104Sjkim */ 473197104Sjkim NextIdString = ACPI_CAST_PTR (char, Info->CompatibleIdList.Ids); 474197104Sjkim if (CidList) 475197104Sjkim { 476241973Sjkim /* Point past the CID PNP_DEVICE_ID array */ 47767754Smsmith 478241973Sjkim NextIdString += ((ACPI_SIZE) CidList->Count * sizeof (ACPI_PNP_DEVICE_ID)); 479197104Sjkim } 480197104Sjkim 481197104Sjkim /* 482241973Sjkim * Copy the HID, UID, SUB, and CIDs to the return buffer. 483241973Sjkim * The variable-length strings are copied to the reserved area 484241973Sjkim * at the end of the buffer. 485197104Sjkim * 486197104Sjkim * For HID and CID, check if the ID is a PCI Root Bridge. 487197104Sjkim */ 488197104Sjkim if (Hid) 48967754Smsmith { 490197104Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->HardwareId, 491197104Sjkim Hid, NextIdString); 492197104Sjkim 493197104Sjkim if (AcpiUtIsPciRootBridge (Hid->String)) 494197104Sjkim { 495197104Sjkim Info->Flags |= ACPI_PCI_ROOT_BRIDGE; 496197104Sjkim } 49767754Smsmith } 49867754Smsmith 499197104Sjkim if (Uid) 500197104Sjkim { 501197104Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->UniqueId, 502197104Sjkim Uid, NextIdString); 503197104Sjkim } 504117521Snjl 505241973Sjkim if (Sub) 506241973Sjkim { 507241973Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->SubsystemId, 508241973Sjkim Sub, NextIdString); 509241973Sjkim } 510241973Sjkim 511117521Snjl if (CidList) 51267754Smsmith { 513197104Sjkim Info->CompatibleIdList.Count = CidList->Count; 514197104Sjkim Info->CompatibleIdList.ListSize = CidList->ListSize; 515197104Sjkim 516197104Sjkim /* Copy each CID */ 517197104Sjkim 518197104Sjkim for (i = 0; i < CidList->Count; i++) 519197104Sjkim { 520197104Sjkim NextIdString = AcpiNsCopyDeviceId (&Info->CompatibleIdList.Ids[i], 521197104Sjkim &CidList->Ids[i], NextIdString); 522197104Sjkim 523197104Sjkim if (AcpiUtIsPciRootBridge (CidList->Ids[i].String)) 524197104Sjkim { 525197104Sjkim Info->Flags |= ACPI_PCI_ROOT_BRIDGE; 526197104Sjkim } 527197104Sjkim } 52867754Smsmith } 52967754Smsmith 530197104Sjkim /* Copy the fixed-length data */ 53167754Smsmith 532197104Sjkim Info->InfoSize = InfoSize; 533197104Sjkim Info->Type = Type; 534197104Sjkim Info->Name = Name; 535197104Sjkim Info->ParamCount = ParamCount; 536197104Sjkim Info->Valid = Valid; 537197104Sjkim 538197104Sjkim *ReturnBuffer = Info; 539197104Sjkim Status = AE_OK; 540197104Sjkim 541197104Sjkim 542117521SnjlCleanup: 543197104Sjkim if (Hid) 544197104Sjkim { 545197104Sjkim ACPI_FREE (Hid); 546197104Sjkim } 547197104Sjkim if (Uid) 548197104Sjkim { 549197104Sjkim ACPI_FREE (Uid); 550197104Sjkim } 551241973Sjkim if (Sub) 552241973Sjkim { 553241973Sjkim ACPI_FREE (Sub); 554241973Sjkim } 555117521Snjl if (CidList) 55667754Smsmith { 557167802Sjkim ACPI_FREE (CidList); 55867754Smsmith } 559117521Snjl return (Status); 56067754Smsmith} 56167754Smsmith 562167802SjkimACPI_EXPORT_SYMBOL (AcpiGetObjectInfo) 563167802Sjkim 564193267Sjkim 565193267Sjkim/****************************************************************************** 566193267Sjkim * 567193267Sjkim * FUNCTION: AcpiInstallMethod 568193267Sjkim * 569193267Sjkim * PARAMETERS: Buffer - An ACPI table containing one control method 570193267Sjkim * 571193267Sjkim * RETURN: Status 572193267Sjkim * 573193267Sjkim * DESCRIPTION: Install a control method into the namespace. If the method 574193267Sjkim * name already exists in the namespace, it is overwritten. The 575193267Sjkim * input buffer must contain a valid DSDT or SSDT containing a 576193267Sjkim * single control method. 577193267Sjkim * 578193267Sjkim ******************************************************************************/ 579193267Sjkim 580193267SjkimACPI_STATUS 581193267SjkimAcpiInstallMethod ( 582193267Sjkim UINT8 *Buffer) 583193267Sjkim{ 584193267Sjkim ACPI_TABLE_HEADER *Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Buffer); 585193267Sjkim UINT8 *AmlBuffer; 586193267Sjkim UINT8 *AmlStart; 587193267Sjkim char *Path; 588193267Sjkim ACPI_NAMESPACE_NODE *Node; 589193267Sjkim ACPI_OPERAND_OBJECT *MethodObj; 590193267Sjkim ACPI_PARSE_STATE ParserState; 591193267Sjkim UINT32 AmlLength; 592193267Sjkim UINT16 Opcode; 593193267Sjkim UINT8 MethodFlags; 594193267Sjkim ACPI_STATUS Status; 595193267Sjkim 596193267Sjkim 597193267Sjkim /* Parameter validation */ 598193267Sjkim 599193267Sjkim if (!Buffer) 600193267Sjkim { 601193267Sjkim return (AE_BAD_PARAMETER); 602193267Sjkim } 603193267Sjkim 604193267Sjkim /* Table must be a DSDT or SSDT */ 605193267Sjkim 606193267Sjkim if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) && 607193267Sjkim !ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT)) 608193267Sjkim { 609193267Sjkim return (AE_BAD_HEADER); 610193267Sjkim } 611193267Sjkim 612193267Sjkim /* First AML opcode in the table must be a control method */ 613193267Sjkim 614193267Sjkim ParserState.Aml = Buffer + sizeof (ACPI_TABLE_HEADER); 615193267Sjkim Opcode = AcpiPsPeekOpcode (&ParserState); 616193267Sjkim if (Opcode != AML_METHOD_OP) 617193267Sjkim { 618193267Sjkim return (AE_BAD_PARAMETER); 619193267Sjkim } 620193267Sjkim 621193267Sjkim /* Extract method information from the raw AML */ 622193267Sjkim 623193267Sjkim ParserState.Aml += AcpiPsGetOpcodeSize (Opcode); 624193267Sjkim ParserState.PkgEnd = AcpiPsGetNextPackageEnd (&ParserState); 625193267Sjkim Path = AcpiPsGetNextNamestring (&ParserState); 626193267Sjkim MethodFlags = *ParserState.Aml++; 627193267Sjkim AmlStart = ParserState.Aml; 628193267Sjkim AmlLength = ACPI_PTR_DIFF (ParserState.PkgEnd, AmlStart); 629193267Sjkim 630193267Sjkim /* 631193267Sjkim * Allocate resources up-front. We don't want to have to delete a new 632193267Sjkim * node from the namespace if we cannot allocate memory. 633193267Sjkim */ 634193267Sjkim AmlBuffer = ACPI_ALLOCATE (AmlLength); 635193267Sjkim if (!AmlBuffer) 636193267Sjkim { 637193267Sjkim return (AE_NO_MEMORY); 638193267Sjkim } 639193267Sjkim 640193267Sjkim MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 641193267Sjkim if (!MethodObj) 642193267Sjkim { 643193267Sjkim ACPI_FREE (AmlBuffer); 644193267Sjkim return (AE_NO_MEMORY); 645193267Sjkim } 646193267Sjkim 647193267Sjkim /* Lock namespace for AcpiNsLookup, we may be creating a new node */ 648193267Sjkim 649193267Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 650193267Sjkim if (ACPI_FAILURE (Status)) 651193267Sjkim { 652193267Sjkim goto ErrorExit; 653193267Sjkim } 654193267Sjkim 655193267Sjkim /* The lookup either returns an existing node or creates a new one */ 656193267Sjkim 657193267Sjkim Status = AcpiNsLookup (NULL, Path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1, 658193267Sjkim ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, NULL, &Node); 659193267Sjkim 660193267Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 661193267Sjkim 662193267Sjkim if (ACPI_FAILURE (Status)) /* NsLookup */ 663193267Sjkim { 664193267Sjkim if (Status != AE_ALREADY_EXISTS) 665193267Sjkim { 666193267Sjkim goto ErrorExit; 667193267Sjkim } 668193267Sjkim 669193267Sjkim /* Node existed previously, make sure it is a method node */ 670193267Sjkim 671193267Sjkim if (Node->Type != ACPI_TYPE_METHOD) 672193267Sjkim { 673193267Sjkim Status = AE_TYPE; 674193267Sjkim goto ErrorExit; 675193267Sjkim } 676193267Sjkim } 677193267Sjkim 678193267Sjkim /* Copy the method AML to the local buffer */ 679193267Sjkim 680193267Sjkim ACPI_MEMCPY (AmlBuffer, AmlStart, AmlLength); 681193267Sjkim 682193267Sjkim /* Initialize the method object with the new method's information */ 683193267Sjkim 684193267Sjkim MethodObj->Method.AmlStart = AmlBuffer; 685193267Sjkim MethodObj->Method.AmlLength = AmlLength; 686193267Sjkim 687193267Sjkim MethodObj->Method.ParamCount = (UINT8) 688193267Sjkim (MethodFlags & AML_METHOD_ARG_COUNT); 689193267Sjkim 690193267Sjkim if (MethodFlags & AML_METHOD_SERIALIZED) 691193267Sjkim { 692217365Sjkim MethodObj->Method.InfoFlags = ACPI_METHOD_SERIALIZED; 693217365Sjkim 694193267Sjkim MethodObj->Method.SyncLevel = (UINT8) 695193267Sjkim ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4); 696193267Sjkim } 697193267Sjkim 698193267Sjkim /* 699193267Sjkim * Now that it is complete, we can attach the new method object to 700193267Sjkim * the method Node (detaches/deletes any existing object) 701193267Sjkim */ 702217365Sjkim Status = AcpiNsAttachObject (Node, MethodObj, ACPI_TYPE_METHOD); 703193267Sjkim 704193267Sjkim /* 705193267Sjkim * Flag indicates AML buffer is dynamic, must be deleted later. 706193267Sjkim * Must be set only after attach above. 707193267Sjkim */ 708193267Sjkim Node->Flags |= ANOBJ_ALLOCATED_BUFFER; 709193267Sjkim 710193267Sjkim /* Remove local reference to the method object */ 711193267Sjkim 712193267Sjkim AcpiUtRemoveReference (MethodObj); 713193267Sjkim return (Status); 714193267Sjkim 715193267Sjkim 716193267SjkimErrorExit: 717193267Sjkim 718193267Sjkim ACPI_FREE (AmlBuffer); 719193267Sjkim ACPI_FREE (MethodObj); 720193267Sjkim return (Status); 721193267Sjkim} 722193267Sjkim 723193267SjkimACPI_EXPORT_SYMBOL (AcpiInstallMethod) 724