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/9a2b638a 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> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
cbc823405a
commit
f65358e572
7 changed files with 164 additions and 13 deletions
|
@ -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_pci_cls_to_string(char *dest, u8 class_code[3]);
|
||||
|
||||
u8 acpi_is_valid_space_id(u8 space_id);
|
||||
|
||||
/*
|
||||
|
|
|
@ -430,6 +430,10 @@ acpi_status
|
|||
acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
|
@ -276,11 +276,12 @@ acpi_get_object_info(acpi_handle handle,
|
|||
struct acpi_pnp_device_id *hid = NULL;
|
||||
struct acpi_pnp_device_id *uid = NULL;
|
||||
struct acpi_pnp_device_id *sub = NULL;
|
||||
struct acpi_pnp_device_id *cls = NULL;
|
||||
char *next_id_string;
|
||||
acpi_object_type type;
|
||||
acpi_name name;
|
||||
u8 param_count = 0;
|
||||
u8 valid = 0;
|
||||
u16 valid = 0;
|
||||
u32 info_size;
|
||||
u32 i;
|
||||
acpi_status status;
|
||||
|
@ -320,7 +321,7 @@ acpi_get_object_info(acpi_handle handle,
|
|||
if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) {
|
||||
/*
|
||||
* 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
|
||||
|
@ -363,6 +364,14 @@ acpi_get_object_info(acpi_handle handle,
|
|||
sizeof(struct acpi_pnp_device_id_list));
|
||||
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,
|
|||
}
|
||||
}
|
||||
|
||||
if (cls) {
|
||||
next_id_string = acpi_ns_copy_device_id(&info->class_code,
|
||||
cls, next_id_string);
|
||||
}
|
||||
|
||||
/* Copy the fixed-length data */
|
||||
|
||||
info->info_size = info_size;
|
||||
|
@ -510,6 +524,9 @@ cleanup:
|
|||
if (cid_list) {
|
||||
ACPI_FREE(cid_list);
|
||||
}
|
||||
if (cls) {
|
||||
ACPI_FREE(cls);
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
@ -416,3 +416,92 @@ cleanup:
|
|||
acpi_ut_remove_reference(obj_desc);
|
||||
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 @@
|
|||
#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"
|
||||
|
|
|
@ -1141,6 +1141,10 @@ u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported);
|
|||
|
||||
#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 */
|
||||
|
||||
struct acpi_pnp_device_id {
|
||||
|
@ -1163,7 +1167,7 @@ struct acpi_device_info {
|
|||
u32 name; /* ACPI object Name */
|
||||
acpi_object_type type; /* ACPI object Type */
|
||||
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 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */
|
||||
u8 lowest_dstates[5]; /* _sx_w values: 0xFF indicates not valid */
|
||||
|
@ -1172,6 +1176,7 @@ struct acpi_device_info {
|
|||
struct acpi_pnp_device_id hardware_id; /* _HID value */
|
||||
struct acpi_pnp_device_id unique_id; /* _UID 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> */
|
||||
};
|
||||
|
||||
|
@ -1181,14 +1186,15 @@ struct acpi_device_info {
|
|||
|
||||
/* Flags for Valid field above (acpi_get_object_info) */
|
||||
|
||||
#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 (current_status above) */
|
||||
|
||||
|
|
Loading…
Reference in a new issue