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

Commit 428f2112 authored by Alexey Starikovskiy's avatar Alexey Starikovskiy Committed by Len Brown
Browse files

ACPICA: Miscellaneous table manager updates and optimizations

parent 77f6a9fc
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -103,7 +103,7 @@ int __init acpi_blacklisted(void)
{
	int i = 0;
	int blacklisted = 0;
	struct acpi_table_header *table_header;
	struct acpi_table_header table_header;

	while (acpi_blacklist[i].oem_id[0] != '\0') {
		if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) {
@@ -111,13 +111,13 @@ int __init acpi_blacklisted(void)
			continue;
		}

		if (strncmp(acpi_blacklist[i].oem_id, table_header->oem_id, 6)) {
		if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) {
			i++;
			continue;
		}

		if (strncmp
		    (acpi_blacklist[i].oem_table_id, table_header->oem_table_id,
		    (acpi_blacklist[i].oem_table_id, table_header.oem_table_id,
		     8)) {
			i++;
			continue;
@@ -126,14 +126,14 @@ int __init acpi_blacklisted(void)
		if ((acpi_blacklist[i].oem_revision_predicate == all_versions)
		    || (acpi_blacklist[i].oem_revision_predicate ==
			less_than_or_equal
			&& table_header->oem_revision <=
			&& table_header.oem_revision <=
			acpi_blacklist[i].oem_revision)
		    || (acpi_blacklist[i].oem_revision_predicate ==
			greater_than_or_equal
			&& table_header->oem_revision >=
			&& table_header.oem_revision >=
			acpi_blacklist[i].oem_revision)
		    || (acpi_blacklist[i].oem_revision_predicate == equal
			&& table_header->oem_revision ==
			&& table_header.oem_revision ==
			acpi_blacklist[i].oem_revision)) {

			printk(KERN_ERR PREFIX
+6 −2
Original line number Diff line number Diff line
@@ -279,13 +279,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
	acpi_native_uint table_index;
	acpi_physical_address address;
	struct acpi_table_header table_header;
	struct acpi_table_desc table_desc;
	acpi_integer temp;
	u32 i;

	ACPI_FUNCTION_TRACE(ex_load_op);

	/* Object can be either an op_region or a Field */

	ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
	case ACPI_TYPE_REGION:

@@ -408,10 +409,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
		goto cleanup;
	}

	table_desc.pointer = table_ptr;
	table_desc.length = table_ptr->length;
	table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
	/*
	 * Install the new table into the local data structures
	 */
	status = acpi_tb_add_table(table_ptr, &table_index);
	status = acpi_tb_add_table(&table_desc, &table_index);
	if (ACPI_FAILURE(status)) {
		goto cleanup;
	}
+54 −37
Original line number Diff line number Diff line
@@ -61,16 +61,19 @@ ACPI_MODULE_NAME("tbinstal")
 *****************************************************************************/
acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
{
	acpi_status status;
	acpi_status status = AE_OK;

	ACPI_FUNCTION_TRACE(tb_verify_table);

	/* Map the table if necessary */

	if (!table_desc->pointer) {
		if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
		    ACPI_TABLE_ORIGIN_MAPPED) {
			table_desc->pointer =
		    acpi_tb_map(table_desc->address, table_desc->length,
				table_desc->flags & ACPI_TABLE_ORIGIN_MASK);
			    acpi_os_map_memory(table_desc->address,
					       table_desc->length);
		}
		if (!table_desc->pointer) {
			return_ACPI_STATUS(AE_NO_MEMORY);
		}
@@ -78,14 +81,15 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)

	/* FACS is the odd table, has no standard ACPI header and no checksum */

	if (ACPI_COMPARE_NAME(&(table_desc->signature), ACPI_SIG_FACS)) {
		return_ACPI_STATUS(AE_OK);
	}
	if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) {

		/* Always calculate checksum, ignore bad checksum if requested */

		status =
	    acpi_tb_verify_checksum(table_desc->pointer, table_desc->length);
		    acpi_tb_verify_checksum(table_desc->pointer,
					    table_desc->length);
	}

	return_ACPI_STATUS(status);
}

@@ -93,7 +97,7 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
 *
 * FUNCTION:    acpi_tb_add_table
 *
 * PARAMETERS:  Table               - Pointer to the table header
 * PARAMETERS:  table_desc          - Table descriptor
 *              table_index         - Where the table index is returned
 *
 * RETURN:      Status
@@ -103,7 +107,7 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
 ******************************************************************************/

acpi_status
acpi_tb_add_table(struct acpi_table_header *table,
acpi_tb_add_table(struct acpi_table_desc *table_desc,
		  acpi_native_uint * table_index)
{
	acpi_native_uint i;
@@ -112,6 +116,25 @@ acpi_tb_add_table(struct acpi_table_header *table,

	ACPI_FUNCTION_TRACE(tb_add_table);

	if (!table_desc->pointer) {
		status = acpi_tb_verify_table(table_desc);
		if (ACPI_FAILURE(status) || !table_desc->pointer) {
			return_ACPI_STATUS(status);
		}
	}

	/* The table must be either an SSDT or a PSDT */

	if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT))
	    &&
	    (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)))
	{
		ACPI_ERROR((AE_INFO,
			    "Table has invalid signature [%4.4s], must be SSDT or PSDT",
			    table_desc->pointer->signature));
		return_ACPI_STATUS(AE_BAD_SIGNATURE);
	}

	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);

	/* Check if table is already registered */
@@ -127,18 +150,17 @@ acpi_tb_add_table(struct acpi_table_header *table,
			}
		}

		length = ACPI_MIN(table->length,
				  acpi_gbl_root_table_list.tables[i].pointer->
				  length);
		if (ACPI_MEMCMP
		    (table, acpi_gbl_root_table_list.tables[i].pointer,
		length = ACPI_MIN(table_desc->length,
				  acpi_gbl_root_table_list.tables[i].length);
		if (ACPI_MEMCMP(table_desc->pointer,
				acpi_gbl_root_table_list.tables[i].pointer,
				length)) {
			continue;
		}

		/* Table is already registered */

		ACPI_FREE(table);
		acpi_tb_delete_table(table_desc);
		*table_index = i;
		goto release;
	}
@@ -146,14 +168,14 @@ acpi_tb_add_table(struct acpi_table_header *table,
	/*
	 * Add the table to the global table list
	 */
	status = acpi_tb_store_table(ACPI_TO_INTEGER(table),
				     table, table->length,
				     ACPI_TABLE_ORIGIN_ALLOCATED, table_index);
	status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
				     table_desc->length, table_desc->flags,
				     table_index);
	if (ACPI_FAILURE(status)) {
		goto release;
	}

	acpi_tb_print_table_header(0, table);
	acpi_tb_print_table_header(table_desc->address, table_desc->pointer);

      release:
	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
@@ -282,25 +304,20 @@ acpi_tb_store_table(acpi_physical_address address,
 *
 ******************************************************************************/

void acpi_tb_delete_table(acpi_native_uint table_index)
void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
{
	struct acpi_table_desc *table_desc;

	/* table_index assumed valid */

	table_desc = &acpi_gbl_root_table_list.tables[table_index];

	/* Table must be mapped or allocated */

	if (!table_desc->pointer) {
		return;
	}

	if (table_desc->flags & ACPI_TABLE_ORIGIN_MAPPED) {
		acpi_tb_unmap(table_desc->pointer, table_desc->length,
			      table_desc->flags & ACPI_TABLE_ORIGIN_MASK);
	} else if (table_desc->flags & ACPI_TABLE_ORIGIN_ALLOCATED) {
	switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
	case ACPI_TABLE_ORIGIN_MAPPED:
		acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
		break;
	case ACPI_TABLE_ORIGIN_ALLOCATED:
		ACPI_FREE(table_desc->pointer);
		break;
	default:;
	}

	table_desc->pointer = NULL;
@@ -329,7 +346,7 @@ void acpi_tb_terminate(void)
	/* Delete the individual tables */

	for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
		acpi_tb_delete_table(i);
		acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]);
	}

	/*
+0 −46
Original line number Diff line number Diff line
@@ -462,49 +462,3 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)

	return_ACPI_STATUS(AE_OK);
}

/******************************************************************************
 *
 * FUNCTION:    acpi_tb_map
 *
 * PARAMETERS:  Address             - Address to be mapped
 *              Length              - Length to be mapped
 *              Flags               - Logical or physical addressing mode
 *
 * RETURN:      Pointer to mapped region
 *
 * DESCRIPTION: Maps memory according to flag
 *
 *****************************************************************************/

void *acpi_tb_map(acpi_physical_address address, u32 length, u32 flags)
{

	if (flags == ACPI_TABLE_ORIGIN_MAPPED) {
		return (acpi_os_map_memory(address, length));
	} else {
		return (ACPI_CAST_PTR(void, address));
	}
}

/******************************************************************************
 *
 * FUNCTION:    acpi_tb_unmap
 *
 * PARAMETERS:  Pointer             - To mapped region
 *              Length              - Length to be unmapped
 *              Flags               - Logical or physical addressing mode
 *
 * RETURN:      None
 *
 * DESCRIPTION: Unmaps memory according to flag
 *
 *****************************************************************************/

void acpi_tb_unmap(void *pointer, u32 length, u32 flags)
{

	if (flags == ACPI_TABLE_ORIGIN_MAPPED) {
		acpi_os_unmap_memory(pointer, length);
	}
}
+39 −15
Original line number Diff line number Diff line
@@ -220,16 +220,25 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
{
	acpi_status status;
	acpi_native_uint table_index;
	struct acpi_table_desc table_desc;

	if (!table_ptr)
		return AE_BAD_PARAMETER;

	ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
	table_desc.pointer = table_ptr;
	table_desc.length = table_ptr->length;
	table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN;

	/*
	 * Install the new table into the local data structures
	 */
	status = acpi_tb_add_table(table_ptr, &table_index);
	status = acpi_tb_add_table(&table_desc, &table_index);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
		return status;
	}
	status = acpi_ns_load_table(table_index, acpi_gbl_root_node);
	return_ACPI_STATUS(status);
	return status;
}

ACPI_EXPORT_SYMBOL(acpi_load_table)
@@ -240,8 +249,7 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
 *
 * PARAMETERS:  Signature           - ACPI signature of needed table
 *              Instance            - Which instance (for SSDTs)
 *              out_table_header    - Where the pointer to the table header
 *                                    is returned
 *              out_table_header    - The pointer to the table header to fill
 *
 * RETURN:      Status and pointer to mapped table header
 *
@@ -254,10 +262,11 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
acpi_status
acpi_get_table_header(char *signature,
		      acpi_native_uint instance,
		      struct acpi_table_header **out_table_header)
		      struct acpi_table_header *out_table_header)
{
	acpi_native_uint i;
	acpi_native_uint j;
	struct acpi_table_header *header;

	/* Parameter validation */

@@ -279,16 +288,31 @@ acpi_get_table_header(char *signature,
			continue;
		}

		*out_table_header =
		    acpi_tb_map(acpi_gbl_root_table_list.tables[i].address,
				(u32) sizeof(struct acpi_table_header),
				acpi_gbl_root_table_list.tables[i].
				flags & ACPI_TABLE_ORIGIN_MASK);

		if (!(*out_table_header)) {
			return (AE_NO_MEMORY);
		if (!acpi_gbl_root_table_list.tables[i].pointer) {
			if ((acpi_gbl_root_table_list.tables[i].
			     flags & ACPI_TABLE_ORIGIN_MASK) ==
			    ACPI_TABLE_ORIGIN_MAPPED) {
				header =
				    acpi_os_map_memory(acpi_gbl_root_table_list.
						       tables[i].address,
						       sizeof(struct
							      acpi_table_header));
				if (!header) {
					return AE_NO_MEMORY;
				}
				ACPI_MEMCPY(out_table_header, header,
					    sizeof(struct acpi_table_header));
				acpi_os_unmap_memory(header,
						     sizeof(struct
							    acpi_table_header));
			} else {
				return AE_NOT_FOUND;
			}
		} else {
			ACPI_MEMCPY(out_table_header,
				    acpi_gbl_root_table_list.tables[i].pointer,
				    sizeof(struct acpi_table_header));
		}

		return (AE_OK);
	}

Loading