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_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
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* 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,
|
||||||
* 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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 @@ cleanup:
|
||||||
if (cid_list) {
|
if (cid_list) {
|
||||||
ACPI_FREE(cid_list);
|
ACPI_FREE(cid_list);
|
||||||
}
|
}
|
||||||
|
if (cls) {
|
||||||
|
ACPI_FREE(cls);
|
||||||
|
}
|
||||||
return (status);
|
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);
|
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 @@
|
||||||
#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);
|
||||||
|
|
||||||
#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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
|
|
||||||
/* 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) */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue