Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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: 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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);

/*
+4 −0
Original line number Diff line number Diff line
@@ -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
 */
+32 −0
Original line number Diff line number Diff line
@@ -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
+20 −3
Original line number Diff line number Diff line
@@ -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 @@ acpi_get_object_info(acpi_handle handle,
	if (cid_list) {
		ACPI_FREE(cid_list);
	}
	if (cls) {
		ACPI_FREE(cls);
	}
	return (status);
}

+90 −1
Original line number Diff line number Diff line
/******************************************************************************
 *
 * 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,
	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);
}
Loading