Commit f65358e5 authored by Suravee Suthikulpanit's avatar Suravee Suthikulpanit Committed by Rafael J. Wysocki

ACPICA: Utilities: Add _CLS processing

ACPICA commit 9a2b638acb3a7215209432e070c6bd0312374229

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.

Link: https://github.com/acpica/acpica/commit/9a2b638aAcked-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: default avatarHanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: default avatarSuravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent cbc82340
...@@ -468,6 +468,8 @@ void acpi_ex_eisa_id_to_string(char *dest, u64 compressed_id); ...@@ -468,6 +468,8 @@ void acpi_ex_eisa_id_to_string(char *dest, u64 compressed_id);
void acpi_ex_integer_to_string(char *dest, u64 value); void acpi_ex_integer_to_string(char *dest, u64 value);
void acpi_ex_pci_cls_to_string(char *dest, u8 class_code[3]);
u8 acpi_is_valid_space_id(u8 space_id); u8 acpi_is_valid_space_id(u8 space_id);
/* /*
......
...@@ -430,6 +430,10 @@ acpi_status ...@@ -430,6 +430,10 @@ acpi_status
acpi_ut_execute_CID(struct acpi_namespace_node *device_node, acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
struct acpi_pnp_device_id_list ** return_cid_list); struct acpi_pnp_device_id_list ** return_cid_list);
acpi_status
acpi_ut_execute_CLS(struct acpi_namespace_node *device_node,
struct acpi_pnp_device_id **return_id);
/* /*
* utlock - reader/writer locks * utlock - reader/writer locks
*/ */
......
...@@ -378,6 +378,38 @@ void acpi_ex_integer_to_string(char *out_string, u64 value) ...@@ -378,6 +378,38 @@ void acpi_ex_integer_to_string(char *out_string, u64 value)
} }
} }
/*******************************************************************************
*
* FUNCTION: acpi_ex_pci_cls_to_string
*
* PARAMETERS: out_string - Where to put the converted string (7 bytes)
* PARAMETERS: class_code - 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 acpi_ex_pci_cls_to_string(char *out_string, u8 class_code[3])
{
ACPI_FUNCTION_ENTRY();
/* All 3 bytes are hexadecimal */
out_string[0] = acpi_ut_hex_to_ascii_char((u64)class_code[0], 4);
out_string[1] = acpi_ut_hex_to_ascii_char((u64)class_code[0], 0);
out_string[2] = acpi_ut_hex_to_ascii_char((u64)class_code[1], 4);
out_string[3] = acpi_ut_hex_to_ascii_char((u64)class_code[1], 0);
out_string[4] = acpi_ut_hex_to_ascii_char((u64)class_code[2], 4);
out_string[5] = acpi_ut_hex_to_ascii_char((u64)class_code[2], 0);
out_string[6] = 0;
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_is_valid_space_id * FUNCTION: acpi_is_valid_space_id
......
...@@ -260,7 +260,7 @@ static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest, ...@@ -260,7 +260,7 @@ static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest,
* control methods (Such as in the case of a device.) * control methods (Such as in the case of a device.)
* *
* For Device and Processor objects, run the Device _HID, _UID, _CID, _SUB, * For Device and Processor objects, run the Device _HID, _UID, _CID, _SUB,
* _STA, _ADR, _sx_w, and _sx_d methods. * _CLS, _STA, _ADR, _sx_w, and _sx_d methods.
* *
* Note: Allocates the return buffer, must be freed by the caller. * Note: Allocates the return buffer, must be freed by the caller.
* *
...@@ -276,11 +276,12 @@ acpi_get_object_info(acpi_handle handle, ...@@ -276,11 +276,12 @@ acpi_get_object_info(acpi_handle handle,
struct acpi_pnp_device_id *hid = NULL; struct acpi_pnp_device_id *hid = NULL;
struct acpi_pnp_device_id *uid = NULL; struct acpi_pnp_device_id *uid = NULL;
struct acpi_pnp_device_id *sub = NULL; struct acpi_pnp_device_id *sub = NULL;
struct acpi_pnp_device_id *cls = NULL;
char *next_id_string; char *next_id_string;
acpi_object_type type; acpi_object_type type;
acpi_name name; acpi_name name;
u8 param_count = 0; u8 param_count = 0;
u8 valid = 0; u16 valid = 0;
u32 info_size; u32 info_size;
u32 i; u32 i;
acpi_status status; acpi_status status;
...@@ -320,7 +321,7 @@ acpi_get_object_info(acpi_handle handle, ...@@ -320,7 +321,7 @@ acpi_get_object_info(acpi_handle handle,
if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) {
/* /*
* Get extra info for ACPI Device/Processor objects only: * 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 * Note: none of these methods are required, so they may or may
* not be present for this device. The Info->Valid bitfield is used * not be present for this device. The Info->Valid bitfield is used
...@@ -363,6 +364,14 @@ acpi_get_object_info(acpi_handle handle, ...@@ -363,6 +364,14 @@ acpi_get_object_info(acpi_handle handle,
sizeof(struct acpi_pnp_device_id_list)); sizeof(struct acpi_pnp_device_id_list));
valid |= ACPI_VALID_CID; valid |= ACPI_VALID_CID;
} }
/* Execute the Device._CLS method */
status = acpi_ut_execute_CLS(node, &cls);
if (ACPI_SUCCESS(status)) {
info_size += cls->length;
valid |= ACPI_VALID_CLS;
}
} }
/* /*
...@@ -486,6 +495,11 @@ acpi_get_object_info(acpi_handle handle, ...@@ -486,6 +495,11 @@ acpi_get_object_info(acpi_handle handle,
} }
} }
if (cls) {
next_id_string = acpi_ns_copy_device_id(&info->class_code,
cls, next_id_string);
}
/* Copy the fixed-length data */ /* Copy the fixed-length data */
info->info_size = info_size; info->info_size = info_size;
...@@ -510,6 +524,9 @@ acpi_get_object_info(acpi_handle handle, ...@@ -510,6 +524,9 @@ acpi_get_object_info(acpi_handle handle,
if (cid_list) { if (cid_list) {
ACPI_FREE(cid_list); ACPI_FREE(cid_list);
} }
if (cls) {
ACPI_FREE(cls);
}
return (status); return (status);
} }
......
/****************************************************************************** /******************************************************************************
* *
* Module Name: utids - support for device Ids - HID, UID, CID * Module Name: utids - support for device Ids - HID, UID, CID, SUB, CLS
* *
*****************************************************************************/ *****************************************************************************/
...@@ -416,3 +416,92 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node, ...@@ -416,3 +416,92 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
acpi_ut_remove_reference(obj_desc); acpi_ut_remove_reference(obj_desc);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ut_execute_CLS
*
* PARAMETERS: device_node - Node for the device
* return_id - 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
acpi_ut_execute_CLS(struct acpi_namespace_node *device_node,
struct acpi_pnp_device_id **return_id)
{
union acpi_operand_object *obj_desc;
union acpi_operand_object **cls_objects;
u32 count;
struct acpi_pnp_device_id *cls;
u32 length;
acpi_status status;
u8 class_code[3] = { 0, 0, 0 };
ACPI_FUNCTION_TRACE(ut_execute_CLS);
status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CLS,
ACPI_BTYPE_PACKAGE, &obj_desc);
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;
cls_objects = obj_desc->package.elements;
count = obj_desc->package.count;
if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
if (count > 0
&& cls_objects[0]->common.type == ACPI_TYPE_INTEGER) {
class_code[0] = (u8)cls_objects[0]->integer.value;
}
if (count > 1
&& cls_objects[1]->common.type == ACPI_TYPE_INTEGER) {
class_code[1] = (u8)cls_objects[1]->integer.value;
}
if (count > 2
&& cls_objects[2]->common.type == ACPI_TYPE_INTEGER) {
class_code[2] = (u8)cls_objects[2]->integer.value;
}
}
/* Allocate a buffer for the CLS */
cls =
ACPI_ALLOCATE_ZEROED(sizeof(struct 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(struct acpi_pnp_device_id));
/* Simply copy existing string */
acpi_ex_pci_cls_to_string(cls->string, class_code);
cls->length = length;
*return_id = cls;
cleanup:
/* On exit, we must delete the return object */
acpi_ut_remove_reference(obj_desc);
return_ACPI_STATUS(status);
}
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#define METHOD_NAME__BBN "_BBN" #define METHOD_NAME__BBN "_BBN"
#define METHOD_NAME__CBA "_CBA" #define METHOD_NAME__CBA "_CBA"
#define METHOD_NAME__CID "_CID" #define METHOD_NAME__CID "_CID"
#define METHOD_NAME__CLS "_CLS"
#define METHOD_NAME__CRS "_CRS" #define METHOD_NAME__CRS "_CRS"
#define METHOD_NAME__DDN "_DDN" #define METHOD_NAME__DDN "_DDN"
#define METHOD_NAME__HID "_HID" #define METHOD_NAME__HID "_HID"
......
...@@ -1141,6 +1141,10 @@ u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported); ...@@ -1141,6 +1141,10 @@ u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported);
#define ACPI_UUID_LENGTH 16 #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 */ /* Structures used for device/processor HID, UID, CID, and SUB */
struct acpi_pnp_device_id { struct acpi_pnp_device_id {
...@@ -1163,7 +1167,7 @@ struct acpi_device_info { ...@@ -1163,7 +1167,7 @@ struct acpi_device_info {
u32 name; /* ACPI object Name */ u32 name; /* ACPI object Name */
acpi_object_type type; /* ACPI object Type */ acpi_object_type type; /* ACPI object Type */
u8 param_count; /* If a method, required parameter count */ u8 param_count; /* If a method, required parameter count */
u8 valid; /* Indicates which optional fields are valid */ u16 valid; /* Indicates which optional fields are valid */
u8 flags; /* Miscellaneous info */ u8 flags; /* Miscellaneous info */
u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */ u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */
u8 lowest_dstates[5]; /* _sx_w values: 0xFF indicates not valid */ u8 lowest_dstates[5]; /* _sx_w values: 0xFF indicates not valid */
...@@ -1172,6 +1176,7 @@ struct acpi_device_info { ...@@ -1172,6 +1176,7 @@ struct acpi_device_info {
struct acpi_pnp_device_id hardware_id; /* _HID value */ struct acpi_pnp_device_id hardware_id; /* _HID value */
struct acpi_pnp_device_id unique_id; /* _UID value */ struct acpi_pnp_device_id unique_id; /* _UID value */
struct acpi_pnp_device_id subsystem_id; /* _SUB value */ struct acpi_pnp_device_id subsystem_id; /* _SUB value */
struct acpi_pnp_device_id class_code; /* _CLS value */
struct acpi_pnp_device_id_list compatible_id_list; /* _CID list <must be last> */ struct acpi_pnp_device_id_list compatible_id_list; /* _CID list <must be last> */
}; };
...@@ -1181,14 +1186,15 @@ struct acpi_device_info { ...@@ -1181,14 +1186,15 @@ struct acpi_device_info {
/* Flags for Valid field above (acpi_get_object_info) */ /* Flags for Valid field above (acpi_get_object_info) */
#define ACPI_VALID_STA 0x01 #define ACPI_VALID_STA 0x0001
#define ACPI_VALID_ADR 0x02 #define ACPI_VALID_ADR 0x0002
#define ACPI_VALID_HID 0x04 #define ACPI_VALID_HID 0x0004
#define ACPI_VALID_UID 0x08 #define ACPI_VALID_UID 0x0008
#define ACPI_VALID_SUB 0x10 #define ACPI_VALID_SUB 0x0010
#define ACPI_VALID_CID 0x20 #define ACPI_VALID_CID 0x0020
#define ACPI_VALID_SXDS 0x40 #define ACPI_VALID_CLS 0x0040
#define ACPI_VALID_SXWS 0x80 #define ACPI_VALID_SXDS 0x0100
#define ACPI_VALID_SXWS 0x0200
/* Flags for _STA return value (current_status above) */ /* Flags for _STA return value (current_status above) */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment