Пример #1
0
acpi_status
acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
{
	acpi_status status;

	ACPI_FUNCTION_TRACE(ns_load_table);

	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	

	if (acpi_tb_is_table_loaded(table_index)) {
		status = AE_ALREADY_EXISTS;
		goto unlock;
	}

	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "**** Loading table into namespace ****\n"));

	status = acpi_tb_allocate_owner_id(table_index);
	if (ACPI_FAILURE(status)) {
		goto unlock;
	}

	status = acpi_ns_parse_table(table_index, node);
	if (ACPI_SUCCESS(status)) {
		acpi_tb_set_table_loaded_flag(table_index, TRUE);
	} else {
		(void)acpi_tb_release_owner_id(table_index);
	}

      unlock:
	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);

	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "**** Begin Table Method Parsing and Object Initialization\n"));

	status = acpi_ds_initialize_objects(table_index, node);

	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "**** Completed Table Method Parsing and Object Initialization\n"));

	return_ACPI_STATUS(status);
}
Пример #2
0
acpi_status
acpi_ns_load_table(acpi_native_uint table_index,
           struct acpi_namespace_node *node)
{
    acpi_status status;

    ACPI_FUNCTION_TRACE(ns_load_table);

    /*
     * Parse the table and load the namespace with all named
     * objects found within.  Control methods are NOT parsed
     * at this time.  In fact, the control methods cannot be
     * parsed until the entire namespace is loaded, because
     * if a control method makes a forward reference (call)
     * to another control method, we can't continue parsing
     * because we don't know how many arguments to parse next!
     */
    status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE(status)) {
        return_ACPI_STATUS(status);
    }

    /* If table already loaded into namespace, just return */

    if (acpi_tb_is_table_loaded(table_index)) {
        status = AE_ALREADY_EXISTS;
        goto unlock;
    }

    ACPI_DEBUG_PRINT((ACPI_DB_INFO,
              "**** Loading table into namespace ****\n"));

    status = acpi_tb_allocate_owner_id(table_index);
    if (ACPI_FAILURE(status)) {
        goto unlock;
    }

    status = acpi_ns_parse_table(table_index, node);
    if (ACPI_SUCCESS(status)) {
        acpi_tb_set_table_loaded_flag(table_index, TRUE);
    } else {
        (void)acpi_tb_release_owner_id(table_index);
    }

      unlock:
    (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);

    if (ACPI_FAILURE(status)) {
        return_ACPI_STATUS(status);
    }

    /*
     * Now we can parse the control methods.  We always parse
     * them here for a sanity check, and if configured for
     * just-in-time parsing, we delete the control method
     * parse trees.
     */
    ACPI_DEBUG_PRINT((ACPI_DB_INFO,
              "**** Begin Table Method Parsing and Object Initialization ****\n"));

    status = acpi_ds_initialize_objects(table_index, node);

    ACPI_DEBUG_PRINT((ACPI_DB_INFO,
              "**** Completed Table Method Parsing and Object Initialization ****\n"));

    return_ACPI_STATUS(status);
}
Пример #3
0
acpi_status
acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
{
	acpi_status status;

	ACPI_FUNCTION_TRACE(ns_load_table);

	/* If table already loaded into namespace, just return */

	if (acpi_tb_is_table_loaded(table_index)) {
		status = AE_ALREADY_EXISTS;
		goto unlock;
	}

	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "**** Loading table into namespace ****\n"));

	status = acpi_tb_allocate_owner_id(table_index);
	if (ACPI_FAILURE(status)) {
		goto unlock;
	}

	/*
	 * Parse the table and load the namespace with all named
	 * objects found within. Control methods are NOT parsed
	 * at this time. In fact, the control methods cannot be
	 * parsed until the entire namespace is loaded, because
	 * if a control method makes a forward reference (call)
	 * to another control method, we can't continue parsing
	 * because we don't know how many arguments to parse next!
	 */
	status = acpi_ns_parse_table(table_index, node);
	if (ACPI_SUCCESS(status)) {
		acpi_tb_set_table_loaded_flag(table_index, TRUE);
	} else {
		/*
		 * On error, delete any namespace objects created by this table.
		 * We cannot initialize these objects, so delete them. There are
		 * a couple of especially bad cases:
		 * AE_ALREADY_EXISTS - namespace collision.
		 * AE_NOT_FOUND - the target of a Scope operator does not
		 * exist. This target of Scope must already exist in the
		 * namespace, as per the ACPI specification.
		 */
		acpi_ns_delete_namespace_by_owner(acpi_gbl_root_table_list.
						  tables[table_index].owner_id);

		acpi_tb_release_owner_id(table_index);
		return_ACPI_STATUS(status);
	}

unlock:
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/*
	 * Now we can parse the control methods. We always parse
	 * them here for a sanity check, and if configured for
	 * just-in-time parsing, we delete the control method
	 * parse trees.
	 */
	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "**** Begin Table Object Initialization\n"));

	acpi_ex_enter_interpreter();
	status = acpi_ds_initialize_objects(table_index, node);
	acpi_ex_exit_interpreter();

	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "**** Completed Table Object Initialization\n"));

	/*
	 * This case handles the legacy option that groups all module-level
	 * code blocks together and defers execution until all of the tables
	 * are loaded. Execute all of these blocks at this time.
	 * Execute any module-level code that was detected during the table
	 * load phase.
	 *
	 * Note: this option is deprecated and will be eliminated in the
	 * future. Use of this option can cause problems with AML code that
	 * depends upon in-order immediate execution of module-level code.
	 */
	acpi_ns_exec_module_code_list();
	return_ACPI_STATUS(status);
}
Пример #4
0
acpi_status
acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
{
	acpi_status status;

	ACPI_FUNCTION_TRACE(ns_load_table);

	/*
	 * Parse the table and load the namespace with all named
	 * objects found within. Control methods are NOT parsed
	 * at this time. In fact, the control methods cannot be
	 * parsed until the entire namespace is loaded, because
	 * if a control method makes a forward reference (call)
	 * to another control method, we can't continue parsing
	 * because we don't know how many arguments to parse next!
	 */
	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/* If table already loaded into namespace, just return */

	if (acpi_tb_is_table_loaded(table_index)) {
		status = AE_ALREADY_EXISTS;
		goto unlock;
	}

	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "**** Loading table into namespace ****\n"));

	status = acpi_tb_allocate_owner_id(table_index);
	if (ACPI_FAILURE(status)) {
		goto unlock;
	}

	status = acpi_ns_parse_table(table_index, node);
	if (ACPI_SUCCESS(status)) {
		acpi_tb_set_table_loaded_flag(table_index, TRUE);
	} else {
		/*
		 * On error, delete any namespace objects created by this table.
		 * We cannot initialize these objects, so delete them. There are
		 * a couple of expecially bad cases:
		 * AE_ALREADY_EXISTS - namespace collision.
		 * AE_NOT_FOUND - the target of a Scope operator does not
		 * exist. This target of Scope must already exist in the
		 * namespace, as per the ACPI specification.
		 */
		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
		acpi_ns_delete_namespace_by_owner(acpi_gbl_root_table_list.
						  tables[table_index].owner_id);

		acpi_tb_release_owner_id(table_index);
		return_ACPI_STATUS(status);
	}

unlock:
	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);

	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/*
	 * Now we can parse the control methods. We always parse
	 * them here for a sanity check, and if configured for
	 * just-in-time parsing, we delete the control method
	 * parse trees.
	 */
	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "**** Begin Table Object Initialization\n"));

	status = acpi_ds_initialize_objects(table_index, node);

	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "**** Completed Table Object Initialization\n"));

	/*
	 * Execute any module-level code that was detected during the table load
	 * phase. Although illegal since ACPI 2.0, there are many machines that
	 * contain this type of code. Each block of detected executable AML code
	 * outside of any control method is wrapped with a temporary control
	 * method object and placed on a global list. The methods on this list
	 * are executed below.
	 *
	 * This case executes the module-level code for each table immediately
	 * after the table has been loaded. This provides compatibility with
	 * other ACPI implementations. Optionally, the execution can be deferred
	 * until later, see acpi_initialize_objects.
	 */
	if (!acpi_gbl_group_module_level_code) {
		acpi_ns_exec_module_code_list();
	}

	return_ACPI_STATUS(status);
}
Пример #5
0
/*******************************************************************************
 *
 * FUNCTION:    acpi_unload_parent_table
 *
 * PARAMETERS:  object              - Handle to any namespace object owned by
 *                                    the table to be unloaded
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Via any namespace object within an SSDT or OEMx table, unloads
 *              the table and deletes all namespace objects associated with
 *              that table. Unloading of the DSDT is not allowed.
 *              Note: Mainly intended to support hotplug removal of SSDTs.
 *
 ******************************************************************************/
acpi_status acpi_unload_parent_table(acpi_handle object)
{
	struct acpi_namespace_node *node =
	    ACPI_CAST_PTR(struct acpi_namespace_node, object);
	acpi_status status = AE_NOT_EXIST;
	acpi_owner_id owner_id;
	u32 i;

	ACPI_FUNCTION_TRACE(acpi_unload_parent_table);

	/* Parameter validation */

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

	/*
	 * The node owner_id is currently the same as the parent table ID.
	 * However, this could change in the future.
	 */
	owner_id = node->owner_id;
	if (!owner_id) {

		/* owner_id==0 means DSDT is the owner. DSDT cannot be unloaded */

		return_ACPI_STATUS(AE_TYPE);
	}

	/* Must acquire the interpreter lock during this operation */

	status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/* Find the table in the global table list */

	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
		if (owner_id != acpi_gbl_root_table_list.tables[i].owner_id) {
			continue;
		}

		/*
		 * Allow unload of SSDT and OEMx tables only. Do not allow unload
		 * of the DSDT. No other types of tables should get here, since
		 * only these types can contain AML and thus are the only types
		 * that can create namespace objects.
		 */
		if (ACPI_COMPARE_NAME
		    (acpi_gbl_root_table_list.tables[i].signature.ascii,
		     ACPI_SIG_DSDT)) {
			status = AE_TYPE;
			break;
		}

		/* Ensure the table is actually loaded */

		if (!acpi_tb_is_table_loaded(i)) {
			status = AE_NOT_EXIST;
			break;
		}

		/* Invoke table handler if present */

		if (acpi_gbl_table_handler) {
			(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
						     acpi_gbl_root_table_list.
						     tables[i].pointer,
						     acpi_gbl_table_handler_context);
		}

		/*
		 * Delete all namespace objects owned by this table. Note that
		 * these objects can appear anywhere in the namespace by virtue
		 * of the AML "Scope" operator. Thus, we need to track ownership
		 * by an ID, not simply a position within the hierarchy.
		 */
		status = acpi_tb_delete_namespace_by_owner(i);
		if (ACPI_FAILURE(status)) {
			break;
		}

		status = acpi_tb_release_owner_id(i);
		acpi_tb_set_table_loaded_flag(i, FALSE);
		break;
	}

	(void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
	return_ACPI_STATUS(status);
}