示例#1
0
文件: tbinstal.c 项目: hugh712/Jollen
void
acpi_tb_free_acpi_tables_of_type (
    acpi_table_desc         *list_head)
{
    acpi_table_desc         *table_desc;
    u32                     count;
    u32                     i;


    FUNCTION_TRACE_PTR ("Tb_free_acpi_tables_of_type", list_head);


    /* Get the head of the list */

    table_desc  = list_head;
    count       = list_head->count;

    /*
     * Walk the entire list, deleting both the allocated tables
     * and the table descriptors
     */
    for (i = 0; i < count; i++) {
        table_desc = acpi_tb_uninstall_table (table_desc);
    }

    return_VOID;
}
示例#2
0
/*******************************************************************************
 *
 * FUNCTION:    acpi_reallocate_root_table
 *
 * PARAMETERS:  None
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
 *              root list from the previously provided scratch area. Should
 *              be called once dynamic memory allocation is available in the
 *              kernel.
 *
 ******************************************************************************/
acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
{
	acpi_status status;
	struct acpi_table_desc *table_desc;
	u32 i, j;

	ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);

	/*
	 * Only reallocate the root table if the host provided a static buffer
	 * for the table array in the call to acpi_initialize_tables.
	 */
	if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
		return_ACPI_STATUS(AE_SUPPORT);
	}

	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);

	/*
	 * Ensure OS early boot logic, which is required by some hosts. If the
	 * table state is reported to be wrong, developers should fix the
	 * issue by invoking acpi_put_table() for the reported table during the
	 * early stage.
	 */
	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
		table_desc = &acpi_gbl_root_table_list.tables[i];
		if (table_desc->pointer) {
			ACPI_ERROR((AE_INFO,
				    "Table [%4.4s] is not invalidated during early boot stage",
				    table_desc->signature.ascii));
		}
	}

	if (!acpi_gbl_enable_table_validation) {
		/*
		 * Now it's safe to do full table validation. We can do deferred
		 * table initilization here once the flag is set.
		 */
		acpi_gbl_enable_table_validation = TRUE;
		for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
		     ++i) {
			table_desc = &acpi_gbl_root_table_list.tables[i];
			if (!(table_desc->flags & ACPI_TABLE_IS_VERIFIED)) {
				status =
				    acpi_tb_verify_temp_table(table_desc, NULL,
							      &j);
				if (ACPI_FAILURE(status)) {
					acpi_tb_uninstall_table(table_desc);
				}
			}
		}
	}

	acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
	status = acpi_tb_resize_root_table_list();
	acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;

	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
	return_ACPI_STATUS(status);
}
示例#3
0
void acpi_tb_terminate(void)
{
	u32 i;

	ACPI_FUNCTION_TRACE(tb_terminate);

	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);

	/* Delete the individual tables */

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

	/*
	 * Delete the root table array if allocated locally. Array cannot be
	 * mapped, so we don't need to check for that flag.
	 */
	if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
		ACPI_FREE(acpi_gbl_root_table_list.tables);
	}

	acpi_gbl_root_table_list.tables = NULL;
	acpi_gbl_root_table_list.flags = 0;
	acpi_gbl_root_table_list.current_table_count = 0;

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));

	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
	return_VOID;
}
示例#4
0
acpi_status
acpi_load_table (
	acpi_table_header       *table_ptr)
{
	acpi_status             status;
	acpi_table_desc         table_info;


	FUNCTION_TRACE ("Acpi_load_table");


	if (!table_ptr) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	/* Copy the table to a local buffer */

	status = acpi_tb_get_table (0, table_ptr, &table_info);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Install the new table into the local data structures */

	status = acpi_tb_install_table (NULL, &table_info);
	if (ACPI_FAILURE (status)) {
		/* Free table allocated by Acpi_tb_get_table */

		acpi_tb_delete_single_table (&table_info);
		return_ACPI_STATUS (status);
	}


	status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node);
	if (ACPI_FAILURE (status)) {
		/* Uninstall table and free the buffer */

		acpi_tb_uninstall_table (table_info.installed_desc);
		return_ACPI_STATUS (status);
	}


	return_ACPI_STATUS (status);
}
acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
{
	acpi_status status = AE_OK;
	union acpi_operand_object *table_desc = ddb_handle;
	struct acpi_table_desc *table_info;

	ACPI_FUNCTION_TRACE("ex_unload_table");

	/*
	 * Validate the handle
	 * Although the handle is partially validated in acpi_ex_reconfiguration(),
	 * when it calls acpi_ex_resolve_operands(), the handle is more completely
	 * validated here.
	 */
	if ((!ddb_handle) ||
	    (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
	    (ACPI_GET_OBJECT_TYPE(ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	/* Get the actual table descriptor from the ddb_handle */

	table_info = (struct acpi_table_desc *)table_desc->reference.object;

	/*
	 * Delete the entire namespace under this table Node
	 * (Offset contains the table_id)
	 */
	acpi_ns_delete_namespace_by_owner(table_info->owner_id);
	acpi_ut_release_owner_id(&table_info->owner_id);

	/* Delete the table itself */

	(void)acpi_tb_uninstall_table(table_info->installed_desc);

	/* Delete the table descriptor (ddb_handle) */

	acpi_ut_remove_reference(table_desc);
	return_ACPI_STATUS(status);
}
acpi_status
acpi_load_table (
    struct acpi_table_header        *table_ptr)
{
    acpi_status                     status;
    struct acpi_table_desc          table_info;
    struct acpi_pointer             address;


    ACPI_FUNCTION_TRACE ("acpi_load_table");


    if (!table_ptr) {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /* Copy the table to a local buffer */

    address.pointer_type    = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
    address.pointer.logical = table_ptr;

    status = acpi_tb_get_table_body (&address, table_ptr, &table_info);
    if (ACPI_FAILURE (status)) {
        return_ACPI_STATUS (status);
    }

    /* Install the new table into the local data structures */

    status = acpi_tb_install_table (&table_info);
    if (ACPI_FAILURE (status)) {
        /* Free table allocated by acpi_tb_get_table_body */

        acpi_tb_delete_single_table (&table_info);
        return_ACPI_STATUS (status);
    }

    /* Convert the table to common format if necessary */

    switch (table_info.type) {
    case ACPI_TABLE_FADT:

        status = acpi_tb_convert_table_fadt ();
        break;

    case ACPI_TABLE_FACS:

        status = acpi_tb_build_common_facs (&table_info);
        break;

    default:
        /* Load table into namespace if it contains executable AML */

        status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node);
        break;
    }

    if (ACPI_FAILURE (status)) {
        /* Uninstall table and free the buffer */

        (void) acpi_tb_uninstall_table (table_info.installed_desc);
    }

    return_ACPI_STATUS (status);
}
示例#7
0
static acpi_status
acpi_ex_add_table(struct acpi_table_header *table,
		  struct acpi_namespace_node *parent_node,
		  union acpi_operand_object **ddb_handle)
{
	acpi_status status;
	struct acpi_table_desc table_info;
	union acpi_operand_object *obj_desc;

	ACPI_FUNCTION_TRACE(ex_add_table);

	/* Create an object to be the table handle */

	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
	if (!obj_desc) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	/* Init the table handle */

	obj_desc->reference.opcode = AML_LOAD_OP;
	*ddb_handle = obj_desc;

	/* Install the new table into the local data structures */

	ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc));

	table_info.type = ACPI_TABLE_ID_SSDT;
	table_info.pointer = table;
	table_info.length = (acpi_size) table->length;
	table_info.allocation = ACPI_MEM_ALLOCATED;

	status = acpi_tb_install_table(&table_info);
	obj_desc->reference.object = table_info.installed_desc;

	if (ACPI_FAILURE(status)) {
		if (status == AE_ALREADY_EXISTS) {

			/* Table already exists, just return the handle */

			return_ACPI_STATUS(AE_OK);
		}
		goto cleanup;
	}

	/* Add the table to the namespace */

	status = acpi_ns_load_table(table_info.installed_desc, parent_node);
	if (ACPI_FAILURE(status)) {

		/* Uninstall table on error */

		(void)acpi_tb_uninstall_table(table_info.installed_desc);
		goto cleanup;
	}

	return_ACPI_STATUS(AE_OK);

      cleanup:
	acpi_ut_remove_reference(obj_desc);
	*ddb_handle = NULL;
	return_ACPI_STATUS(status);
}
void acpi_tb_delete_tables_by_type(acpi_table_type type)
{
	struct acpi_table_desc *table_desc;
	u32 count;
	u32 i;

	ACPI_FUNCTION_TRACE_U32(tb_delete_tables_by_type, type);

	if (type > ACPI_TABLE_ID_MAX) {
		return_VOID;
	}

	if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_TABLES))) {
		return;
	}

	/* Clear the appropriate "typed" global table pointer */

	switch (type) {
	case ACPI_TABLE_ID_RSDP:
		acpi_gbl_RSDP = NULL;
		break;

	case ACPI_TABLE_ID_DSDT:
		acpi_gbl_DSDT = NULL;
		break;

	case ACPI_TABLE_ID_FADT:
		acpi_gbl_FADT = NULL;
		break;

	case ACPI_TABLE_ID_FACS:
		acpi_gbl_FACS = NULL;
		break;

	case ACPI_TABLE_ID_XSDT:
		acpi_gbl_XSDT = NULL;
		break;

	case ACPI_TABLE_ID_SSDT:
	case ACPI_TABLE_ID_PSDT:
	default:
		break;
	}

	/*
	 * Free the table
	 * 1) Get the head of the list
	 */
	table_desc = acpi_gbl_table_lists[type].next;
	count = acpi_gbl_table_lists[type].count;

	/*
	 * 2) Walk the entire list, deleting both the allocated tables
	 *    and the table descriptors
	 */
	for (i = 0; i < count; i++) {
		table_desc = acpi_tb_uninstall_table(table_desc);
	}

	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
	return_VOID;
}