Skip to content

Commit

Permalink
Utilities: Add _CLS processing
Browse files Browse the repository at this point in the history
ACPI Device object often contains a _CLS object to supply PCI-defined class
code for the device. This patch introduces logic to process the _CLS
object. Suravee Suthikulpanit, Lv Zheng.

Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
  • Loading branch information
ssuthiku-amd authored and Lv Zheng committed May 20, 2015
1 parent ecb91f4 commit 9a2b638
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 13 deletions.
37 changes: 37 additions & 0 deletions source/components/executer/exutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,43 @@ AcpiExIntegerToString (
}


/*******************************************************************************
*
* FUNCTION: AcpiExPciClsToString
*
* PARAMETERS: OutString - Where to put the converted string (7 bytes)
* PARAMETERS: ClassCode - PCI class code to be converted (3 bytes)
*
* RETURN: None
*
* DESCRIPTION: Convert 3-bytes PCI class code to string representation.
* Return buffer must be large enough to hold the string. The
* string returned is always exactly of length
* ACPI_PCICLS_STRING_SIZE (includes null terminator).
*
******************************************************************************/

void
AcpiExPciClsToString (
char *OutString,
UINT8 ClassCode[3])
{

ACPI_FUNCTION_ENTRY ();


/* All 3 bytes are hexadecimal */

OutString[0] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[0], 4);
OutString[1] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[0], 0);
OutString[2] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[1], 4);
OutString[3] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[1], 0);
OutString[4] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[2], 4);
OutString[5] = AcpiUtHexToAsciiChar ((UINT64) ClassCode[2], 0);
OutString[6] = 0;
}


/*******************************************************************************
*
* FUNCTION: AcpiIsValidSpaceId
Expand Down
26 changes: 23 additions & 3 deletions source/components/namespace/nsxfname.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ AcpiNsCopyDeviceId (
* control methods (Such as in the case of a device.)
*
* For Device and Processor objects, run the Device _HID, _UID, _CID, _SUB,
* _STA, _ADR, _SxW, and _SxD methods.
* _CLS, _STA, _ADR, _SxW, and _SxD methods.
*
* Note: Allocates the return buffer, must be freed by the caller.
*
Expand All @@ -379,11 +379,12 @@ AcpiGetObjectInfo (
ACPI_PNP_DEVICE_ID *Hid = NULL;
ACPI_PNP_DEVICE_ID *Uid = NULL;
ACPI_PNP_DEVICE_ID *Sub = NULL;
ACPI_PNP_DEVICE_ID *Cls = NULL;
char *NextIdString;
ACPI_OBJECT_TYPE Type;
ACPI_NAME Name;
UINT8 ParamCount= 0;
UINT8 Valid = 0;
UINT16 Valid = 0;
UINT32 InfoSize;
UINT32 i;
ACPI_STATUS Status;
Expand Down Expand Up @@ -431,7 +432,7 @@ AcpiGetObjectInfo (
{
/*
* Get extra info for ACPI Device/Processor objects only:
* Run the Device _HID, _UID, _SUB, and _CID methods.
* Run the Device _HID, _UID, _SUB, _CID, and _CLS methods.
*
* Note: none of these methods are required, so they may or may
* not be present for this device. The Info->Valid bitfield is used
Expand Down Expand Up @@ -475,6 +476,15 @@ AcpiGetObjectInfo (
InfoSize += (CidList->ListSize - sizeof (ACPI_PNP_DEVICE_ID_LIST));
Valid |= ACPI_VALID_CID;
}

/* Execute the Device._CLS method */

Status = AcpiUtExecute_CLS (Node, &Cls);
if (ACPI_SUCCESS (Status))
{
InfoSize += Cls->Length;
Valid |= ACPI_VALID_CLS;
}
}

/*
Expand Down Expand Up @@ -606,6 +616,12 @@ AcpiGetObjectInfo (
}
}

if (Cls)
{
NextIdString = AcpiNsCopyDeviceId (&Info->ClassCode,
Cls, NextIdString);
}

/* Copy the fixed-length data */

Info->InfoSize = InfoSize;
Expand Down Expand Up @@ -635,6 +651,10 @@ AcpiGetObjectInfo (
{
ACPI_FREE (CidList);
}
if (Cls)
{
ACPI_FREE (Cls);
}
return (Status);
}

Expand Down
96 changes: 95 additions & 1 deletion source/components/utilities/utids.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
*
* Module Name: utids - support for device IDs - HID, UID, CID
* Module Name: utids - support for device IDs - HID, UID, CID, SUB, CLS
*
*****************************************************************************/

Expand Down Expand Up @@ -521,3 +521,97 @@ AcpiUtExecute_CID (
AcpiUtRemoveReference (ObjDesc);
return_ACPI_STATUS (Status);
}


/*******************************************************************************
*
* FUNCTION: AcpiUtExecute_CLS
*
* PARAMETERS: DeviceNode - Node for the device
* ReturnId - Where the _CLS is returned
*
* RETURN: Status
*
* DESCRIPTION: Executes the _CLS control method that returns PCI-defined
* class code of the device. The _CLS value is always a package
* containing PCI class information as a list of integers.
* The returned string has format "BBSSPP", where:
* BB = Base-class code
* SS = Sub-class code
* PP = Programming Interface code
*
******************************************************************************/

ACPI_STATUS
AcpiUtExecute_CLS (
ACPI_NAMESPACE_NODE *DeviceNode,
ACPI_PNP_DEVICE_ID **ReturnId)
{
ACPI_OPERAND_OBJECT *ObjDesc;
ACPI_OPERAND_OBJECT **ClsObjects;
UINT32 Count;
ACPI_PNP_DEVICE_ID *Cls;
UINT32 Length;
ACPI_STATUS Status;
UINT8 ClassCode[3] = {0, 0, 0};


ACPI_FUNCTION_TRACE (UtExecute_CLS);


Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__CLS,
ACPI_BTYPE_PACKAGE, &ObjDesc);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}

/* Get the size of the String to be returned, includes null terminator */

Length = ACPI_PCICLS_STRING_SIZE;
ClsObjects = ObjDesc->Package.Elements;
Count = ObjDesc->Package.Count;

if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
{
if (Count > 0 && ClsObjects[0]->Common.Type == ACPI_TYPE_INTEGER)
{
ClassCode[0] = (UINT8) ClsObjects[0]->Integer.Value;
}
if (Count > 1 && ClsObjects[1]->Common.Type == ACPI_TYPE_INTEGER)
{
ClassCode[1] = (UINT8) ClsObjects[1]->Integer.Value;
}
if (Count > 2 && ClsObjects[2]->Common.Type == ACPI_TYPE_INTEGER)
{
ClassCode[2] = (UINT8) ClsObjects[2]->Integer.Value;
}
}

/* Allocate a buffer for the CLS */

Cls = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length);
if (!Cls)
{
Status = AE_NO_MEMORY;
goto Cleanup;
}

/* Area for the string starts after PNP_DEVICE_ID struct */

Cls->String = ACPI_ADD_PTR (char, Cls, sizeof (ACPI_PNP_DEVICE_ID));

/* Simply copy existing string */

AcpiExPciClsToString (Cls->String, ClassCode);
Cls->Length = Length;
*ReturnId = Cls;


Cleanup:

/* On exit, we must delete the return object */

AcpiUtRemoveReference (ObjDesc);
return_ACPI_STATUS (Status);
}
5 changes: 5 additions & 0 deletions source/include/acinterp.h
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,11 @@ AcpiExIntegerToString (
char *Dest,
UINT64 Value);

void
AcpiExPciClsToString (
char *Dest,
UINT8 ClassCode[3]);

BOOLEAN
AcpiIsValidSpaceId (
UINT8 SpaceId);
Expand Down
1 change: 1 addition & 0 deletions source/include/acnames.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define METHOD_NAME__BBN "_BBN"
#define METHOD_NAME__CBA "_CBA"
#define METHOD_NAME__CID "_CID"
#define METHOD_NAME__CLS "_CLS"
#define METHOD_NAME__CRS "_CRS"
#define METHOD_NAME__DDN "_DDN"
#define METHOD_NAME__HID "_HID"
Expand Down
24 changes: 15 additions & 9 deletions source/include/actypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,10 @@ UINT32 (*ACPI_INTERFACE_HANDLER) (

#define ACPI_UUID_LENGTH 16

/* Length of 3-byte PCI class code values when converted back to a string */

#define ACPI_PCICLS_STRING_SIZE 7 /* Includes null terminator */


/* Structures used for device/processor HID, UID, CID, and SUB */

Expand Down Expand Up @@ -1327,7 +1331,7 @@ typedef struct acpi_device_info
UINT32 Name; /* ACPI object Name */
ACPI_OBJECT_TYPE Type; /* ACPI object Type */
UINT8 ParamCount; /* If a method, required parameter count */
UINT8 Valid; /* Indicates which optional fields are valid */
UINT16 Valid; /* Indicates which optional fields are valid */
UINT8 Flags; /* Miscellaneous info */
UINT8 HighestDstates[4]; /* _SxD values: 0xFF indicates not valid */
UINT8 LowestDstates[5]; /* _SxW values: 0xFF indicates not valid */
Expand All @@ -1336,6 +1340,7 @@ typedef struct acpi_device_info
ACPI_PNP_DEVICE_ID HardwareId; /* _HID value */
ACPI_PNP_DEVICE_ID UniqueId; /* _UID value */
ACPI_PNP_DEVICE_ID SubsystemId; /* _SUB value */
ACPI_PNP_DEVICE_ID ClassCode; /* _CLS value */
ACPI_PNP_DEVICE_ID_LIST CompatibleIdList; /* _CID list <must be last> */

} ACPI_DEVICE_INFO;
Expand All @@ -1346,14 +1351,15 @@ typedef struct acpi_device_info

/* Flags for Valid field above (AcpiGetObjectInfo) */

#define ACPI_VALID_STA 0x01
#define ACPI_VALID_ADR 0x02
#define ACPI_VALID_HID 0x04
#define ACPI_VALID_UID 0x08
#define ACPI_VALID_SUB 0x10
#define ACPI_VALID_CID 0x20
#define ACPI_VALID_SXDS 0x40
#define ACPI_VALID_SXWS 0x80
#define ACPI_VALID_STA 0x0001
#define ACPI_VALID_ADR 0x0002
#define ACPI_VALID_HID 0x0004
#define ACPI_VALID_UID 0x0008
#define ACPI_VALID_SUB 0x0010
#define ACPI_VALID_CID 0x0020
#define ACPI_VALID_CLS 0x0040
#define ACPI_VALID_SXDS 0x0100
#define ACPI_VALID_SXWS 0x0200

/* Flags for _STA return value (CurrentStatus above) */

Expand Down
5 changes: 5 additions & 0 deletions source/include/acutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,11 @@ AcpiUtExecute_CID (
ACPI_NAMESPACE_NODE *DeviceNode,
ACPI_PNP_DEVICE_ID_LIST **ReturnCidList);

ACPI_STATUS
AcpiUtExecute_CLS (
ACPI_NAMESPACE_NODE *DeviceNode,
ACPI_PNP_DEVICE_ID **ReturnId);


/*
* utlock - reader/writer locks
Expand Down

0 comments on commit 9a2b638

Please sign in to comment.