157190917SDana Myers /****************************************************************************** 257190917SDana Myers * 3*385cc6b4SJerry Jelinek * Module Name: utids - support for device IDs - HID, UID, CID, SUB, CLS 457190917SDana Myers * 557190917SDana Myers *****************************************************************************/ 657190917SDana Myers 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 957190917SDana Myers * All rights reserved. 1057190917SDana Myers * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 2557190917SDana Myers * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 2957190917SDana Myers * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 4357190917SDana Myers 4457190917SDana Myers #include "acpi.h" 4557190917SDana Myers #include "accommon.h" 4657190917SDana Myers #include "acinterp.h" 4757190917SDana Myers 4857190917SDana Myers 4957190917SDana Myers #define _COMPONENT ACPI_UTILITIES 5057190917SDana Myers ACPI_MODULE_NAME ("utids") 5157190917SDana Myers 5257190917SDana Myers 5357190917SDana Myers /******************************************************************************* 5457190917SDana Myers * 5557190917SDana Myers * FUNCTION: AcpiUtExecute_HID 5657190917SDana Myers * 5757190917SDana Myers * PARAMETERS: DeviceNode - Node for the device 5857190917SDana Myers * ReturnId - Where the string HID is returned 5957190917SDana Myers * 6057190917SDana Myers * RETURN: Status 6157190917SDana Myers * 6257190917SDana Myers * DESCRIPTION: Executes the _HID control method that returns the hardware 6357190917SDana Myers * ID of the device. The HID is either an 32-bit encoded EISAID 6457190917SDana Myers * Integer or a String. A string is always returned. An EISAID 6557190917SDana Myers * is converted to a string. 6657190917SDana Myers * 6757190917SDana Myers * NOTE: Internal function, no parameter validation 6857190917SDana Myers * 6957190917SDana Myers ******************************************************************************/ 7057190917SDana Myers 7157190917SDana Myers ACPI_STATUS 7257190917SDana Myers AcpiUtExecute_HID ( 7357190917SDana Myers ACPI_NAMESPACE_NODE *DeviceNode, 74*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID **ReturnId) 7557190917SDana Myers { 7657190917SDana Myers ACPI_OPERAND_OBJECT *ObjDesc; 77*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID *Hid; 7857190917SDana Myers UINT32 Length; 7957190917SDana Myers ACPI_STATUS Status; 8057190917SDana Myers 8157190917SDana Myers 8257190917SDana Myers ACPI_FUNCTION_TRACE (UtExecute_HID); 8357190917SDana Myers 8457190917SDana Myers 8557190917SDana Myers Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__HID, 8657190917SDana Myers ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc); 8757190917SDana Myers if (ACPI_FAILURE (Status)) 8857190917SDana Myers { 8957190917SDana Myers return_ACPI_STATUS (Status); 9057190917SDana Myers } 9157190917SDana Myers 9257190917SDana Myers /* Get the size of the String to be returned, includes null terminator */ 9357190917SDana Myers 9457190917SDana Myers if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER) 9557190917SDana Myers { 9657190917SDana Myers Length = ACPI_EISAID_STRING_SIZE; 9757190917SDana Myers } 9857190917SDana Myers else 9957190917SDana Myers { 10057190917SDana Myers Length = ObjDesc->String.Length + 1; 10157190917SDana Myers } 10257190917SDana Myers 10357190917SDana Myers /* Allocate a buffer for the HID */ 10457190917SDana Myers 105*385cc6b4SJerry Jelinek Hid = ACPI_ALLOCATE_ZEROED ( 106*385cc6b4SJerry Jelinek sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length); 10757190917SDana Myers if (!Hid) 10857190917SDana Myers { 10957190917SDana Myers Status = AE_NO_MEMORY; 11057190917SDana Myers goto Cleanup; 11157190917SDana Myers } 11257190917SDana Myers 113*385cc6b4SJerry Jelinek /* Area for the string starts after PNP_DEVICE_ID struct */ 11457190917SDana Myers 115*385cc6b4SJerry Jelinek Hid->String = ACPI_ADD_PTR (char, Hid, sizeof (ACPI_PNP_DEVICE_ID)); 11657190917SDana Myers 11757190917SDana Myers /* Convert EISAID to a string or simply copy existing string */ 11857190917SDana Myers 11957190917SDana Myers if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER) 12057190917SDana Myers { 12157190917SDana Myers AcpiExEisaIdToString (Hid->String, ObjDesc->Integer.Value); 12257190917SDana Myers } 12357190917SDana Myers else 12457190917SDana Myers { 125*385cc6b4SJerry Jelinek strcpy (Hid->String, ObjDesc->String.Pointer); 12657190917SDana Myers } 12757190917SDana Myers 12857190917SDana Myers Hid->Length = Length; 12957190917SDana Myers *ReturnId = Hid; 13057190917SDana Myers 13157190917SDana Myers 13257190917SDana Myers Cleanup: 13357190917SDana Myers 13457190917SDana Myers /* On exit, we must delete the return object */ 13557190917SDana Myers 13657190917SDana Myers AcpiUtRemoveReference (ObjDesc); 13757190917SDana Myers return_ACPI_STATUS (Status); 13857190917SDana Myers } 13957190917SDana Myers 14057190917SDana Myers 14157190917SDana Myers /******************************************************************************* 14257190917SDana Myers * 14357190917SDana Myers * FUNCTION: AcpiUtExecute_UID 14457190917SDana Myers * 14557190917SDana Myers * PARAMETERS: DeviceNode - Node for the device 14657190917SDana Myers * ReturnId - Where the string UID is returned 14757190917SDana Myers * 14857190917SDana Myers * RETURN: Status 14957190917SDana Myers * 15057190917SDana Myers * DESCRIPTION: Executes the _UID control method that returns the unique 15157190917SDana Myers * ID of the device. The UID is either a 64-bit Integer (NOT an 15257190917SDana Myers * EISAID) or a string. Always returns a string. A 64-bit integer 15357190917SDana Myers * is converted to a decimal string. 15457190917SDana Myers * 15557190917SDana Myers * NOTE: Internal function, no parameter validation 15657190917SDana Myers * 15757190917SDana Myers ******************************************************************************/ 15857190917SDana Myers 15957190917SDana Myers ACPI_STATUS 16057190917SDana Myers AcpiUtExecute_UID ( 16157190917SDana Myers ACPI_NAMESPACE_NODE *DeviceNode, 162*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID **ReturnId) 16357190917SDana Myers { 16457190917SDana Myers ACPI_OPERAND_OBJECT *ObjDesc; 165*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID *Uid; 16657190917SDana Myers UINT32 Length; 16757190917SDana Myers ACPI_STATUS Status; 16857190917SDana Myers 16957190917SDana Myers 17057190917SDana Myers ACPI_FUNCTION_TRACE (UtExecute_UID); 17157190917SDana Myers 17257190917SDana Myers 17357190917SDana Myers Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__UID, 17457190917SDana Myers ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc); 17557190917SDana Myers if (ACPI_FAILURE (Status)) 17657190917SDana Myers { 17757190917SDana Myers return_ACPI_STATUS (Status); 17857190917SDana Myers } 17957190917SDana Myers 18057190917SDana Myers /* Get the size of the String to be returned, includes null terminator */ 18157190917SDana Myers 18257190917SDana Myers if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER) 18357190917SDana Myers { 18457190917SDana Myers Length = ACPI_MAX64_DECIMAL_DIGITS + 1; 18557190917SDana Myers } 18657190917SDana Myers else 18757190917SDana Myers { 18857190917SDana Myers Length = ObjDesc->String.Length + 1; 18957190917SDana Myers } 19057190917SDana Myers 19157190917SDana Myers /* Allocate a buffer for the UID */ 19257190917SDana Myers 193*385cc6b4SJerry Jelinek Uid = ACPI_ALLOCATE_ZEROED ( 194*385cc6b4SJerry Jelinek sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length); 19557190917SDana Myers if (!Uid) 19657190917SDana Myers { 19757190917SDana Myers Status = AE_NO_MEMORY; 19857190917SDana Myers goto Cleanup; 19957190917SDana Myers } 20057190917SDana Myers 201*385cc6b4SJerry Jelinek /* Area for the string starts after PNP_DEVICE_ID struct */ 20257190917SDana Myers 203*385cc6b4SJerry Jelinek Uid->String = ACPI_ADD_PTR (char, Uid, sizeof (ACPI_PNP_DEVICE_ID)); 20457190917SDana Myers 20557190917SDana Myers /* Convert an Integer to string, or just copy an existing string */ 20657190917SDana Myers 20757190917SDana Myers if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER) 20857190917SDana Myers { 20957190917SDana Myers AcpiExIntegerToString (Uid->String, ObjDesc->Integer.Value); 21057190917SDana Myers } 21157190917SDana Myers else 21257190917SDana Myers { 213*385cc6b4SJerry Jelinek strcpy (Uid->String, ObjDesc->String.Pointer); 21457190917SDana Myers } 21557190917SDana Myers 21657190917SDana Myers Uid->Length = Length; 21757190917SDana Myers *ReturnId = Uid; 21857190917SDana Myers 21957190917SDana Myers 22057190917SDana Myers Cleanup: 22157190917SDana Myers 22257190917SDana Myers /* On exit, we must delete the return object */ 22357190917SDana Myers 22457190917SDana Myers AcpiUtRemoveReference (ObjDesc); 22557190917SDana Myers return_ACPI_STATUS (Status); 22657190917SDana Myers } 22757190917SDana Myers 22857190917SDana Myers 22957190917SDana Myers /******************************************************************************* 23057190917SDana Myers * 23157190917SDana Myers * FUNCTION: AcpiUtExecute_CID 23257190917SDana Myers * 23357190917SDana Myers * PARAMETERS: DeviceNode - Node for the device 23457190917SDana Myers * ReturnCidList - Where the CID list is returned 23557190917SDana Myers * 23657190917SDana Myers * RETURN: Status, list of CID strings 23757190917SDana Myers * 23857190917SDana Myers * DESCRIPTION: Executes the _CID control method that returns one or more 23957190917SDana Myers * compatible hardware IDs for the device. 24057190917SDana Myers * 24157190917SDana Myers * NOTE: Internal function, no parameter validation 24257190917SDana Myers * 24357190917SDana Myers * A _CID method can return either a single compatible ID or a package of 24457190917SDana Myers * compatible IDs. Each compatible ID can be one of the following: 24557190917SDana Myers * 1) Integer (32 bit compressed EISA ID) or 24657190917SDana Myers * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") 24757190917SDana Myers * 24857190917SDana Myers * The Integer CIDs are converted to string format by this function. 24957190917SDana Myers * 25057190917SDana Myers ******************************************************************************/ 25157190917SDana Myers 25257190917SDana Myers ACPI_STATUS 25357190917SDana Myers AcpiUtExecute_CID ( 25457190917SDana Myers ACPI_NAMESPACE_NODE *DeviceNode, 255*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID_LIST **ReturnCidList) 25657190917SDana Myers { 25757190917SDana Myers ACPI_OPERAND_OBJECT **CidObjects; 25857190917SDana Myers ACPI_OPERAND_OBJECT *ObjDesc; 259*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID_LIST *CidList; 26057190917SDana Myers char *NextIdString; 26157190917SDana Myers UINT32 StringAreaSize; 26257190917SDana Myers UINT32 Length; 26357190917SDana Myers UINT32 CidListSize; 26457190917SDana Myers ACPI_STATUS Status; 26557190917SDana Myers UINT32 Count; 26657190917SDana Myers UINT32 i; 26757190917SDana Myers 26857190917SDana Myers 26957190917SDana Myers ACPI_FUNCTION_TRACE (UtExecute_CID); 27057190917SDana Myers 27157190917SDana Myers 27257190917SDana Myers /* Evaluate the _CID method for this device */ 27357190917SDana Myers 27457190917SDana Myers Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__CID, 27557190917SDana Myers ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE, 27657190917SDana Myers &ObjDesc); 27757190917SDana Myers if (ACPI_FAILURE (Status)) 27857190917SDana Myers { 27957190917SDana Myers return_ACPI_STATUS (Status); 28057190917SDana Myers } 28157190917SDana Myers 28257190917SDana Myers /* 28357190917SDana Myers * Get the count and size of the returned _CIDs. _CID can return either 28457190917SDana Myers * a Package of Integers/Strings or a single Integer or String. 28557190917SDana Myers * Note: This section also validates that all CID elements are of the 28657190917SDana Myers * correct type (Integer or String). 28757190917SDana Myers */ 28857190917SDana Myers if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE) 28957190917SDana Myers { 29057190917SDana Myers Count = ObjDesc->Package.Count; 29157190917SDana Myers CidObjects = ObjDesc->Package.Elements; 29257190917SDana Myers } 29357190917SDana Myers else /* Single Integer or String CID */ 29457190917SDana Myers { 29557190917SDana Myers Count = 1; 29657190917SDana Myers CidObjects = &ObjDesc; 29757190917SDana Myers } 29857190917SDana Myers 29957190917SDana Myers StringAreaSize = 0; 30057190917SDana Myers for (i = 0; i < Count; i++) 30157190917SDana Myers { 30257190917SDana Myers /* String lengths include null terminator */ 30357190917SDana Myers 30457190917SDana Myers switch (CidObjects[i]->Common.Type) 30557190917SDana Myers { 30657190917SDana Myers case ACPI_TYPE_INTEGER: 307*385cc6b4SJerry Jelinek 30857190917SDana Myers StringAreaSize += ACPI_EISAID_STRING_SIZE; 30957190917SDana Myers break; 31057190917SDana Myers 31157190917SDana Myers case ACPI_TYPE_STRING: 312*385cc6b4SJerry Jelinek 31357190917SDana Myers StringAreaSize += CidObjects[i]->String.Length + 1; 31457190917SDana Myers break; 31557190917SDana Myers 31657190917SDana Myers default: 317*385cc6b4SJerry Jelinek 31857190917SDana Myers Status = AE_TYPE; 31957190917SDana Myers goto Cleanup; 32057190917SDana Myers } 32157190917SDana Myers } 32257190917SDana Myers 32357190917SDana Myers /* 32457190917SDana Myers * Now that we know the length of the CIDs, allocate return buffer: 32557190917SDana Myers * 1) Size of the base structure + 326*385cc6b4SJerry Jelinek * 2) Size of the CID PNP_DEVICE_ID array + 32757190917SDana Myers * 3) Size of the actual CID strings 32857190917SDana Myers */ 329*385cc6b4SJerry Jelinek CidListSize = sizeof (ACPI_PNP_DEVICE_ID_LIST) + 330*385cc6b4SJerry Jelinek ((Count - 1) * sizeof (ACPI_PNP_DEVICE_ID)) + 33157190917SDana Myers StringAreaSize; 33257190917SDana Myers 33357190917SDana Myers CidList = ACPI_ALLOCATE_ZEROED (CidListSize); 33457190917SDana Myers if (!CidList) 33557190917SDana Myers { 33657190917SDana Myers Status = AE_NO_MEMORY; 33757190917SDana Myers goto Cleanup; 33857190917SDana Myers } 33957190917SDana Myers 340*385cc6b4SJerry Jelinek /* Area for CID strings starts after the CID PNP_DEVICE_ID array */ 34157190917SDana Myers 34257190917SDana Myers NextIdString = ACPI_CAST_PTR (char, CidList->Ids) + 343*385cc6b4SJerry Jelinek ((ACPI_SIZE) Count * sizeof (ACPI_PNP_DEVICE_ID)); 34457190917SDana Myers 34557190917SDana Myers /* Copy/convert the CIDs to the return buffer */ 34657190917SDana Myers 34757190917SDana Myers for (i = 0; i < Count; i++) 34857190917SDana Myers { 34957190917SDana Myers if (CidObjects[i]->Common.Type == ACPI_TYPE_INTEGER) 35057190917SDana Myers { 35157190917SDana Myers /* Convert the Integer (EISAID) CID to a string */ 35257190917SDana Myers 353*385cc6b4SJerry Jelinek AcpiExEisaIdToString ( 354*385cc6b4SJerry Jelinek NextIdString, CidObjects[i]->Integer.Value); 35557190917SDana Myers Length = ACPI_EISAID_STRING_SIZE; 35657190917SDana Myers } 35757190917SDana Myers else /* ACPI_TYPE_STRING */ 35857190917SDana Myers { 35957190917SDana Myers /* Copy the String CID from the returned object */ 36057190917SDana Myers 361*385cc6b4SJerry Jelinek strcpy (NextIdString, CidObjects[i]->String.Pointer); 36257190917SDana Myers Length = CidObjects[i]->String.Length + 1; 36357190917SDana Myers } 36457190917SDana Myers 36557190917SDana Myers CidList->Ids[i].String = NextIdString; 36657190917SDana Myers CidList->Ids[i].Length = Length; 36757190917SDana Myers NextIdString += Length; 36857190917SDana Myers } 36957190917SDana Myers 37057190917SDana Myers /* Finish the CID list */ 37157190917SDana Myers 37257190917SDana Myers CidList->Count = Count; 37357190917SDana Myers CidList->ListSize = CidListSize; 37457190917SDana Myers *ReturnCidList = CidList; 37557190917SDana Myers 37657190917SDana Myers 37757190917SDana Myers Cleanup: 37857190917SDana Myers 37957190917SDana Myers /* On exit, we must delete the _CID return object */ 38057190917SDana Myers 38157190917SDana Myers AcpiUtRemoveReference (ObjDesc); 38257190917SDana Myers return_ACPI_STATUS (Status); 38357190917SDana Myers } 38457190917SDana Myers 385*385cc6b4SJerry Jelinek 386*385cc6b4SJerry Jelinek /******************************************************************************* 387*385cc6b4SJerry Jelinek * 388*385cc6b4SJerry Jelinek * FUNCTION: AcpiUtExecute_CLS 389*385cc6b4SJerry Jelinek * 390*385cc6b4SJerry Jelinek * PARAMETERS: DeviceNode - Node for the device 391*385cc6b4SJerry Jelinek * ReturnId - Where the _CLS is returned 392*385cc6b4SJerry Jelinek * 393*385cc6b4SJerry Jelinek * RETURN: Status 394*385cc6b4SJerry Jelinek * 395*385cc6b4SJerry Jelinek * DESCRIPTION: Executes the _CLS control method that returns PCI-defined 396*385cc6b4SJerry Jelinek * class code of the device. The _CLS value is always a package 397*385cc6b4SJerry Jelinek * containing PCI class information as a list of integers. 398*385cc6b4SJerry Jelinek * The returned string has format "BBSSPP", where: 399*385cc6b4SJerry Jelinek * BB = Base-class code 400*385cc6b4SJerry Jelinek * SS = Sub-class code 401*385cc6b4SJerry Jelinek * PP = Programming Interface code 402*385cc6b4SJerry Jelinek * 403*385cc6b4SJerry Jelinek ******************************************************************************/ 404*385cc6b4SJerry Jelinek 405*385cc6b4SJerry Jelinek ACPI_STATUS 406*385cc6b4SJerry Jelinek AcpiUtExecute_CLS ( 407*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *DeviceNode, 408*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID **ReturnId) 409*385cc6b4SJerry Jelinek { 410*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *ObjDesc; 411*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT **ClsObjects; 412*385cc6b4SJerry Jelinek UINT32 Count; 413*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID *Cls; 414*385cc6b4SJerry Jelinek UINT32 Length; 415*385cc6b4SJerry Jelinek ACPI_STATUS Status; 416*385cc6b4SJerry Jelinek UINT8 ClassCode[3] = {0, 0, 0}; 417*385cc6b4SJerry Jelinek 418*385cc6b4SJerry Jelinek 419*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (UtExecute_CLS); 420*385cc6b4SJerry Jelinek 421*385cc6b4SJerry Jelinek 422*385cc6b4SJerry Jelinek Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__CLS, 423*385cc6b4SJerry Jelinek ACPI_BTYPE_PACKAGE, &ObjDesc); 424*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 425*385cc6b4SJerry Jelinek { 426*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 427*385cc6b4SJerry Jelinek } 428*385cc6b4SJerry Jelinek 429*385cc6b4SJerry Jelinek /* Get the size of the String to be returned, includes null terminator */ 430*385cc6b4SJerry Jelinek 431*385cc6b4SJerry Jelinek Length = ACPI_PCICLS_STRING_SIZE; 432*385cc6b4SJerry Jelinek ClsObjects = ObjDesc->Package.Elements; 433*385cc6b4SJerry Jelinek Count = ObjDesc->Package.Count; 434*385cc6b4SJerry Jelinek 435*385cc6b4SJerry Jelinek if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE) 436*385cc6b4SJerry Jelinek { 437*385cc6b4SJerry Jelinek if (Count > 0 && ClsObjects[0]->Common.Type == ACPI_TYPE_INTEGER) 438*385cc6b4SJerry Jelinek { 439*385cc6b4SJerry Jelinek ClassCode[0] = (UINT8) ClsObjects[0]->Integer.Value; 440*385cc6b4SJerry Jelinek } 441*385cc6b4SJerry Jelinek if (Count > 1 && ClsObjects[1]->Common.Type == ACPI_TYPE_INTEGER) 442*385cc6b4SJerry Jelinek { 443*385cc6b4SJerry Jelinek ClassCode[1] = (UINT8) ClsObjects[1]->Integer.Value; 444*385cc6b4SJerry Jelinek } 445*385cc6b4SJerry Jelinek if (Count > 2 && ClsObjects[2]->Common.Type == ACPI_TYPE_INTEGER) 446*385cc6b4SJerry Jelinek { 447*385cc6b4SJerry Jelinek ClassCode[2] = (UINT8) ClsObjects[2]->Integer.Value; 448*385cc6b4SJerry Jelinek } 449*385cc6b4SJerry Jelinek } 450*385cc6b4SJerry Jelinek 451*385cc6b4SJerry Jelinek /* Allocate a buffer for the CLS */ 452*385cc6b4SJerry Jelinek 453*385cc6b4SJerry Jelinek Cls = ACPI_ALLOCATE_ZEROED ( 454*385cc6b4SJerry Jelinek sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length); 455*385cc6b4SJerry Jelinek if (!Cls) 456*385cc6b4SJerry Jelinek { 457*385cc6b4SJerry Jelinek Status = AE_NO_MEMORY; 458*385cc6b4SJerry Jelinek goto Cleanup; 459*385cc6b4SJerry Jelinek } 460*385cc6b4SJerry Jelinek 461*385cc6b4SJerry Jelinek /* Area for the string starts after PNP_DEVICE_ID struct */ 462*385cc6b4SJerry Jelinek 463*385cc6b4SJerry Jelinek Cls->String = ACPI_ADD_PTR (char, Cls, sizeof (ACPI_PNP_DEVICE_ID)); 464*385cc6b4SJerry Jelinek 465*385cc6b4SJerry Jelinek /* Simply copy existing string */ 466*385cc6b4SJerry Jelinek 467*385cc6b4SJerry Jelinek AcpiExPciClsToString (Cls->String, ClassCode); 468*385cc6b4SJerry Jelinek Cls->Length = Length; 469*385cc6b4SJerry Jelinek *ReturnId = Cls; 470*385cc6b4SJerry Jelinek 471*385cc6b4SJerry Jelinek 472*385cc6b4SJerry Jelinek Cleanup: 473*385cc6b4SJerry Jelinek 474*385cc6b4SJerry Jelinek /* On exit, we must delete the return object */ 475*385cc6b4SJerry Jelinek 476*385cc6b4SJerry Jelinek AcpiUtRemoveReference (ObjDesc); 477*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 478*385cc6b4SJerry Jelinek } 479