Esempio n. 1
0
acpi_status
acpi_ns_evaluate_by_name (
	NATIVE_CHAR             *pathname,
	acpi_operand_object     **params,
	acpi_operand_object     **return_object)
{
	acpi_status             status;
	acpi_namespace_node     *node = NULL;
	NATIVE_CHAR             *internal_path = NULL;


	FUNCTION_TRACE ("Ns_evaluate_by_name");


	/* Build an internal name string for the method */

	status = acpi_ns_internalize_name (pathname, &internal_path);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);

	/* Lookup the name in the namespace */

	status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY,
			 IMODE_EXECUTE, NS_NO_UPSEARCH, NULL,
			 &node);

	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);

	if (ACPI_FAILURE (status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object at [%s] was not found, status=%.4X\n",
			pathname, status));
		goto cleanup;
	}

	/*
	 * Now that we have a handle to the object, we can attempt
	 * to evaluate it.
	 */
	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s [%p] Value %p\n",
		pathname, node, node->object));

	status = acpi_ns_evaluate_by_handle (node, params, return_object);

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "*** Completed eval of object %s ***\n",
		pathname));


cleanup:

	/* Cleanup */

	if (internal_path) {
		ACPI_MEM_FREE (internal_path);
	}

	return_ACPI_STATUS (status);
}
Esempio n. 2
0
static acpi_status
acpi_ev_execute_reg_method (
	union acpi_operand_object      *region_obj,
	u32                             function)
{
	union acpi_operand_object      *params[3];
	union acpi_operand_object      *region_obj2;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("ev_execute_reg_method");


	region_obj2 = acpi_ns_get_secondary_object (region_obj);
	if (!region_obj2) {
		return_ACPI_STATUS (AE_NOT_EXIST);
	}

	if (region_obj2->extra.method_REG == NULL) {
		return_ACPI_STATUS (AE_OK);
	}

	/*
	 * _REG method has two arguments
	 * Arg0:   Integer: Operation region space ID
	 *          Same value as region_obj->Region.space_id
	 * Arg1:   Integer: connection status
	 *          1 for connecting the handler,
	 *          0 for disconnecting the handler
	 *          Passed as a parameter
	 */
	params[0] = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
	if (!params[0]) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	params[1] = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
	if (!params[1]) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

	/* Set up the parameter objects */

	params[0]->integer.value = region_obj->region.space_id;
	params[1]->integer.value = function;
	params[2] = NULL;

	/* Execute the method, no return value */

	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, region_obj2->extra.method_REG, NULL));
	status = acpi_ns_evaluate_by_handle (region_obj2->extra.method_REG, params, NULL);

	acpi_ut_remove_reference (params[1]);

cleanup:
	acpi_ut_remove_reference (params[0]);

	return_ACPI_STATUS (status);
}
Esempio n. 3
0
acpi_status
acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info)
{
	acpi_status status;
	char *internal_path = NULL;

	ACPI_FUNCTION_TRACE("ns_evaluate_by_name");

	/* Build an internal name string for the method */

	status = acpi_ns_internalize_name(pathname, &internal_path);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
		goto cleanup;
	}

	/* Lookup the name in the namespace */

	status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY,
				ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
				&info->node);

	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);

	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
				  "Object at [%s] was not found, status=%.4X\n",
				  pathname, status));
		goto cleanup;
	}

	/*
	 * Now that we have a handle to the object, we can attempt to evaluate it.
	 */
	ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
			  pathname, info->node,
			  acpi_ns_get_attached_object(info->node)));

	status = acpi_ns_evaluate_by_handle(info);

	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
			  "*** Completed eval of object %s ***\n", pathname));

      cleanup:

	/* Cleanup */

	if (internal_path) {
		ACPI_MEM_FREE(internal_path);
	}

	return_ACPI_STATUS(status);
}
Esempio n. 4
0
ACPI_STATUS
acpi_ns_evaluate_by_name (
	NATIVE_CHAR             *pathname,
	ACPI_OPERAND_OBJECT     **params,
	ACPI_OPERAND_OBJECT     **return_object)
{
	ACPI_STATUS             status;
	ACPI_NAMESPACE_NODE     *node = NULL;
	NATIVE_CHAR             *internal_path = NULL;


	/* Build an internal name string for the method */

	status = acpi_ns_internalize_name (pathname, &internal_path);
	if (ACPI_FAILURE (status)) {
		return (status);
	}

	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);

	/* Lookup the name in the namespace */

	status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY,
			 IMODE_EXECUTE, NS_NO_UPSEARCH, NULL,
			 &node);

	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);

	if (ACPI_FAILURE (status)) {
		goto cleanup;
	}

	/*
	 * Now that we have a handle to the object, we can attempt
	 * to evaluate it.
	 */

	status = acpi_ns_evaluate_by_handle (node, params, return_object);


cleanup:

	/* Cleanup */

	if (internal_path) {
		acpi_cm_free (internal_path);
	}

	return (status);
}
Esempio n. 5
0
static ACPI_STATUS
acpi_ev_execute_reg_method (
	ACPI_OPERAND_OBJECT    *region_obj,
	u32                     function)
{
	ACPI_OPERAND_OBJECT    *params[3];
	ACPI_OPERAND_OBJECT     space_iD_obj;
	ACPI_OPERAND_OBJECT     function_obj;
	ACPI_STATUS             status;


	if (region_obj->region.extra->extra.method_REG == NULL) {
		return (AE_OK);
	}

	/*
	 *  _REG method has two arguments
	 *  Arg0:   Integer: Operation region space ID
	 *          Same value as Region_obj->Region.Space_id
	 *  Arg1:   Integer: connection status
	 *          1 for connecting the handler,
	 *          0 for disconnecting the handler
	 *          Passed as a parameter
	 */

	acpi_cm_init_static_object (&space_iD_obj);
	acpi_cm_init_static_object (&function_obj);

	/*
	 *  Method requires two parameters.
	 */
	params [0] = &space_iD_obj;
	params [1] = &function_obj;
	params [2] = NULL;

	/*
	 *  Set up the parameter objects
	 */
	space_iD_obj.common.type   = ACPI_TYPE_NUMBER;
	space_iD_obj.number.value  = region_obj->region.space_id;

	function_obj.common.type   = ACPI_TYPE_NUMBER;
	function_obj.number.value  = function;

	/*
	 *  Execute the method, no return value
	 */
	status = acpi_ns_evaluate_by_handle (region_obj->region.extra->extra.method_REG, params, NULL);
	return (status);
}
Esempio n. 6
0
static void
acpi_ev_asynch_execute_gpe_method (
	void                    *context)
{
	unsigned long           gpe_number = (unsigned long) context;
	acpi_gpe_level_info     gpe_info;


	FUNCTION_TRACE ("Ev_asynch_execute_gpe_method");

	/*
	 * Take a snapshot of the GPE info for this level
	 */
	acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
	gpe_info = acpi_gbl_gpe_info [gpe_number];
	acpi_ut_release_mutex (ACPI_MTX_EVENTS);

	/*
	 * Method Handler (_Lxx, _Exx):
	 * ----------------------------
	 * Evaluate the _Lxx/_Exx control method that corresponds to this GPE.
	 */
	if (gpe_info.method_handle) {
		acpi_ns_evaluate_by_handle (gpe_info.method_handle, NULL, NULL);
	}

	/*
	 * Level-Triggered?
	 * ----------------
	 * If level-triggered we clear the GPE status bit after handling the event.
	 */
	if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) {
		acpi_hw_clear_gpe (gpe_number);
	}

	/*
	 * Enable the GPE.
	 */
	acpi_hw_enable_gpe (gpe_number);

	return_VOID;
}
Esempio n. 7
0
ACPI_STATUS
acpi_ns_evaluate_relative (
	ACPI_NAMESPACE_NODE     *handle,
	NATIVE_CHAR             *pathname,
	ACPI_OPERAND_OBJECT     **params,
	ACPI_OPERAND_OBJECT     **return_object)
{
	ACPI_NAMESPACE_NODE     *prefix_node;
	ACPI_STATUS             status;
	ACPI_NAMESPACE_NODE     *node = NULL;
	NATIVE_CHAR             *internal_path = NULL;
	ACPI_GENERIC_STATE      scope_info;


	/*
	 * Must have a valid object handle
	 */
	if (!handle) {
		return (AE_BAD_PARAMETER);
	}

	/* Build an internal name string for the method */

	status = acpi_ns_internalize_name (pathname, &internal_path);
	if (ACPI_FAILURE (status)) {
		return (status);
	}

	/* Get the prefix handle and Node */

	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);

	prefix_node = acpi_ns_convert_handle_to_entry (handle);
	if (!prefix_node) {
		acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
		status = AE_BAD_PARAMETER;
		goto cleanup;
	}

	/* Lookup the name in the namespace */

	scope_info.scope.node = prefix_node;
	status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY,
			 IMODE_EXECUTE, NS_NO_UPSEARCH, NULL,
			 &node);

	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);

	if (ACPI_FAILURE (status)) {
		goto cleanup;
	}

	/*
	 * Now that we have a handle to the object, we can attempt
	 * to evaluate it.
	 */

	status = acpi_ns_evaluate_by_handle (node, params, return_object);

cleanup:

	/* Cleanup */

	acpi_cm_free (internal_path);

	return (status);
}
Esempio n. 8
0
acpi_status
acpi_ns_evaluate_relative(char *pathname, struct acpi_parameter_info *info)
{
	acpi_status status;
	struct acpi_namespace_node *node = NULL;
	union acpi_generic_state *scope_info;
	char *internal_path = NULL;

	ACPI_FUNCTION_TRACE("ns_evaluate_relative");

	/*
	 * Must have a valid object handle
	 */
	if (!info || !info->node) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	/* Build an internal name string for the method */

	status = acpi_ns_internalize_name(pathname, &internal_path);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	scope_info = acpi_ut_create_generic_state();
	if (!scope_info) {
		goto cleanup1;
	}

	/* Get the prefix handle and Node */

	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
		goto cleanup;
	}

	info->node = acpi_ns_map_handle_to_node(info->node);
	if (!info->node) {
		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
		status = AE_BAD_PARAMETER;
		goto cleanup;
	}

	/* Lookup the name in the namespace */

	scope_info->scope.node = info->node;
	status = acpi_ns_lookup(scope_info, internal_path, ACPI_TYPE_ANY,
				ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
				&node);

	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);

	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Object [%s] not found [%s]\n",
				  pathname, acpi_format_exception(status)));
		goto cleanup;
	}

	/*
	 * Now that we have a handle to the object, we can attempt to evaluate it.
	 */
	ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
			  pathname, node, acpi_ns_get_attached_object(node)));

	info->node = node;
	status = acpi_ns_evaluate_by_handle(info);

	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
			  "*** Completed eval of object %s ***\n", pathname));

      cleanup:
	acpi_ut_delete_generic_state(scope_info);

      cleanup1:
	ACPI_MEM_FREE(internal_path);
	return_ACPI_STATUS(status);
}
Esempio n. 9
0
acpi_status
acpi_evaluate_object (
	acpi_handle                     handle,
	acpi_string                     pathname,
	struct acpi_object_list         *external_params,
	struct acpi_buffer              *return_buffer)
{
	acpi_status                     status;
	acpi_status                     status2;
	struct acpi_parameter_info      info;
	acpi_size                       buffer_space_needed;
	u32                             i;


	ACPI_FUNCTION_TRACE ("acpi_evaluate_object");


	info.node = handle;
	info.parameters = NULL;
	info.return_object = NULL;
	info.parameter_type = ACPI_PARAM_ARGS;

	/*
	 * If there are parameters to be passed to the object
	 * (which must be a control method), the external objects
	 * must be converted to internal objects
	 */
	if (external_params && external_params->count) {
		/*
		 * Allocate a new parameter block for the internal objects
		 * Add 1 to count to allow for null terminated internal list
		 */
		info.parameters = ACPI_MEM_CALLOCATE (
				 ((acpi_size) external_params->count + 1) *
				 sizeof (void *));
		if (!info.parameters) {
			return_ACPI_STATUS (AE_NO_MEMORY);
		}

		/*
		 * Convert each external object in the list to an
		 * internal object
		 */
		for (i = 0; i < external_params->count; i++) {
			status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i],
					  &info.parameters[i]);
			if (ACPI_FAILURE (status)) {
				acpi_ut_delete_internal_object_list (info.parameters);
				return_ACPI_STATUS (status);
			}
		}
		info.parameters[external_params->count] = NULL;
	}


	/*
	 * Three major cases:
	 * 1) Fully qualified pathname
	 * 2) No handle, not fully qualified pathname (error)
	 * 3) Valid handle
	 */
	if ((pathname) &&
		(acpi_ns_valid_root_prefix (pathname[0]))) {
		/*
		 *  The path is fully qualified, just evaluate by name
		 */
		status = acpi_ns_evaluate_by_name (pathname, &info);
	}
	else if (!handle) {
		/*
		 * A handle is optional iff a fully qualified pathname
		 * is specified.  Since we've already handled fully
		 * qualified names above, this is an error
		 */
		if (!pathname) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Both Handle and Pathname are NULL\n"));
		}
		else {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Handle is NULL and Pathname is relative\n"));
		}

		status = AE_BAD_PARAMETER;
	}
	else {
		/*
		 * We get here if we have a handle -- and if we have a
		 * pathname it is relative.  The handle will be validated
		 * in the lower procedures
		 */
		if (!pathname) {
			/*
			 * The null pathname case means the handle is for
			 * the actual object to be evaluated
			 */
			status = acpi_ns_evaluate_by_handle (&info);
		}
		else {
		   /*
			* Both a Handle and a relative Pathname
			*/
			status = acpi_ns_evaluate_relative (pathname, &info);
		}
	}


	/*
	 * If we are expecting a return value, and all went well above,
	 * copy the return value to an external object.
	 */
	if (return_buffer) {
		if (!info.return_object) {
			return_buffer->length = 0;
		}
		else {
			if (ACPI_GET_DESCRIPTOR_TYPE (info.return_object) == ACPI_DESC_TYPE_NAMED) {
				/*
				 * If we received a NS Node as a return object, this means that
				 * the object we are evaluating has nothing interesting to
				 * return (such as a mutex, etc.)  We return an error because
				 * these types are essentially unsupported by this interface.
				 * We don't check up front because this makes it easier to add
				 * support for various types at a later date if necessary.
				 */
				status = AE_TYPE;
				info.return_object = NULL;  /* No need to delete a NS Node */
				return_buffer->length = 0;
			}

			if (ACPI_SUCCESS (status)) {
				/*
				 * Find out how large a buffer is needed
				 * to contain the returned object
				 */
				status = acpi_ut_get_object_size (info.return_object,
						   &buffer_space_needed);
				if (ACPI_SUCCESS (status)) {
					/* Validate/Allocate/Clear caller buffer */

					status = acpi_ut_initialize_buffer (return_buffer, buffer_space_needed);
					if (ACPI_FAILURE (status)) {
						/*
						 * Caller's buffer is too small or a new one can't be allocated
						 */
						ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
							"Needed buffer size %X, %s\n",
							(u32) buffer_space_needed,
							acpi_format_exception (status)));
					}
					else {
						/*
						 *  We have enough space for the object, build it
						 */
						status = acpi_ut_copy_iobject_to_eobject (info.return_object,
								  return_buffer);
					}
				}
			}
		}
	}

	if (info.return_object) {
		/*
		 * Delete the internal return object.  NOTE: Interpreter
		 * must be locked to avoid race condition.
		 */
		status2 = acpi_ex_enter_interpreter ();
		if (ACPI_SUCCESS (status2)) {
			/*
			 * Delete the internal return object. (Or at least
			 * decrement the reference count by one)
			 */
			acpi_ut_remove_reference (info.return_object);
			acpi_ex_exit_interpreter ();
		}
	}

	/*
	 * Free the input parameter list (if we created one),
	 */
	if (info.parameters) {
		/* Free the allocated parameter block */

		acpi_ut_delete_internal_object_list (info.parameters);
	}

	return_ACPI_STATUS (status);
}
Esempio n. 10
0
static void ACPI_SYSTEM_XFACE
acpi_ev_asynch_execute_gpe_method (
	void                            *context)
{
	struct acpi_gpe_event_info      *gpe_event_info = (void *) context;
	u32                             gpe_number = 0;
	acpi_status                     status;
	struct acpi_gpe_event_info      local_gpe_event_info;
	struct acpi_parameter_info      info;


	ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method");


	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_VOID;
	}

	/* Must revalidate the gpe_number/gpe_block */

	if (!acpi_ev_valid_gpe_event (gpe_event_info)) {
		status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
		return_VOID;
	}

	/* Set the GPE flags for return to enabled state */

	(void) acpi_ev_enable_gpe (gpe_event_info, FALSE);

	/*
	 * Take a snapshot of the GPE info for this level - we copy the
	 * info to prevent a race condition with remove_handler/remove_block.
	 */
	ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, sizeof (struct acpi_gpe_event_info));

	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_VOID;
	}

	/*
	 * Must check for control method type dispatch one more
	 * time to avoid race with ev_gpe_install_handler
	 */
	if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) {
		/*
		 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
		 * control method that corresponds to this GPE
		 */
		info.node = local_gpe_event_info.dispatch.method_node;
		info.parameters = ACPI_CAST_PTR (union acpi_operand_object *, gpe_event_info);
		info.parameter_type = ACPI_PARAM_GPE;

		status = acpi_ns_evaluate_by_handle (&info);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR ((
				"%s while evaluating method [%4.4s] for GPE[%2X]\n",
				acpi_format_exception (status),
				acpi_ut_get_node_name (local_gpe_event_info.dispatch.method_node),
				gpe_number));
		}
	}
Esempio n. 11
0
ACPI_STATUS
acpi_evaluate_object (
	ACPI_HANDLE             handle,
	ACPI_STRING             pathname,
	ACPI_OBJECT_LIST        *param_objects,
	ACPI_BUFFER             *return_buffer)
{
	ACPI_STATUS             status;
	ACPI_OPERAND_OBJECT     **param_ptr = NULL;
	ACPI_OPERAND_OBJECT     *return_obj = NULL;
	ACPI_OPERAND_OBJECT     *object_ptr = NULL;
	u32                     buffer_space_needed;
	u32                     user_buffer_length;
	u32                     count;
	u32                     i;
	u32                     param_length;
	u32                     object_length;


	/*
	 * If there are parameters to be passed to the object
	 * (which must be a control method), the external objects
	 * must be converted to internal objects
	 */

	if (param_objects && param_objects->count) {
		/*
		 * Allocate a new parameter block for the internal objects
		 * Add 1 to count to allow for null terminated internal list
		 */

		count           = param_objects->count;
		param_length    = (count + 1) * sizeof (void *);
		object_length   = count * sizeof (ACPI_OPERAND_OBJECT);

		param_ptr = acpi_cm_callocate (param_length + /* Parameter List part */
				  object_length); /* Actual objects */
		if (!param_ptr) {
			return (AE_NO_MEMORY);
		}

		object_ptr = (ACPI_OPERAND_OBJECT *) ((u8 *) param_ptr +
				  param_length);

		/*
		 * Init the param array of pointers and NULL terminate
		 * the list
		 */

		for (i = 0; i < count; i++) {
			param_ptr[i] = &object_ptr[i];
			acpi_cm_init_static_object (&object_ptr[i]);
		}
		param_ptr[count] = NULL;

		/*
		 * Convert each external object in the list to an
		 * internal object
		 */
		for (i = 0; i < count; i++) {
			status =
				acpi_cm_build_internal_object (&param_objects->pointer[i],
						  param_ptr[i]);

			if (ACPI_FAILURE (status)) {
				acpi_cm_delete_internal_object_list (param_ptr);
				return (status);
			}
		}
	}


	/*
	 * Three major cases:
	 * 1) Fully qualified pathname
	 * 2) No handle, not fully qualified pathname (error)
	 * 3) Valid handle
	 */

	if ((pathname) &&
		(acpi_ns_valid_root_prefix (pathname[0])))
	{
		/*
		 *  The path is fully qualified, just evaluate by name
		 */
		status = acpi_ns_evaluate_by_name (pathname, param_ptr, &return_obj);
	}

	else if (!handle) {
		/*
		 * A handle is optional iff a fully qualified pathname
		 * is specified.  Since we've already handled fully
		 * qualified names above, this is an error
		 */



		status = AE_BAD_PARAMETER;
	}

	else {
		/*
		 * We get here if we have a handle -- and if we have a
		 * pathname it is relative.  The handle will be validated
		 * in the lower procedures
		 */

		if (!pathname) {
			/*
			 * The null pathname case means the handle is for
			 * the actual object to be evaluated
			 */
			status = acpi_ns_evaluate_by_handle (handle, param_ptr, &return_obj);
		}

		else {
		   /*
			* Both a Handle and a relative Pathname
			*/
			status = acpi_ns_evaluate_relative (handle, pathname, param_ptr,
					 &return_obj);
		}
	}


	/*
	 * If we are expecting a return value, and all went well above,
	 * copy the return value to an external object.
	 */

	if (return_buffer) {
		user_buffer_length = return_buffer->length;
		return_buffer->length = 0;

		if (return_obj) {
			if (VALID_DESCRIPTOR_TYPE (return_obj, ACPI_DESC_TYPE_NAMED)) {
				/*
				 * If we got an Node as a return object,
				 * this means the object we are evaluating
				 * has nothing interesting to return (such
				 * as a mutex, etc.)  We return an error
				 * because these types are essentially
				 * unsupported by this interface.  We
				 * don't check up front because this makes
				 * it easier to add support for various
				 * types at a later date if necessary.
				 */
				status = AE_TYPE;
				return_obj = NULL;  /* No need to delete an Node */
			}

			if (ACPI_SUCCESS (status)) {
				/*
				 * Find out how large a buffer is needed
				 * to contain the returned object
				 */
				status = acpi_cm_get_object_size (return_obj,
						   &buffer_space_needed);
				if (ACPI_SUCCESS (status)) {
					/*
					 * Check if there is enough room in the
					 * caller's buffer
					 */

					if (user_buffer_length < buffer_space_needed) {
						/*
						 * Caller's buffer is too small, can't
						 * give him partial results fail the call
						 * but return the buffer size needed
						 */

						return_buffer->length = buffer_space_needed;
						status = AE_BUFFER_OVERFLOW;
					}

					else {
						/*
						 *  We have enough space for the object, build it
						 */
						status = acpi_cm_build_external_object (return_obj,
								  return_buffer);
						return_buffer->length = buffer_space_needed;
					}
				}
			}
		}
	}


	/* Delete the return and parameter objects */

	if (return_obj) {
		/*
		 * Delete the internal return object. (Or at least
		 * decrement the reference count by one)
		 */
		acpi_cm_remove_reference (return_obj);
	}

	/*
	 * Free the input parameter list (if we created one),
	 */

	if (param_ptr) {
		/* Free the allocated parameter block */

		acpi_cm_delete_internal_object_list (param_ptr);
	}

	return (status);
}
Esempio n. 12
0
static void ACPI_SYSTEM_XFACE
acpi_ev_asynch_execute_gpe_method (
	void                            *context)
{
	struct acpi_gpe_event_info      *gpe_event_info = (void *) context;
	u32                             gpe_number = 0;
	acpi_status                     status;
	struct acpi_gpe_event_info      local_gpe_event_info;


	ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method");


	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_VOID;
	}

	/* Must revalidate the gpe_number/gpe_block */

	if (!acpi_ev_valid_gpe_event (gpe_event_info)) {
		status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
		return_VOID;
	}

	/*
	 * Take a snapshot of the GPE info for this level - we copy the
	 * info to prevent a race condition with remove_handler/remove_block.
	 */
	ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, sizeof (struct acpi_gpe_event_info));

	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_VOID;
	}

	if (local_gpe_event_info.method_node) {
		/*
		 * Invoke the GPE Method (_Lxx, _Exx):
		 * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.)
		 */
		status = acpi_ns_evaluate_by_handle (local_gpe_event_info.method_node, NULL, NULL);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n",
				acpi_format_exception (status),
				local_gpe_event_info.method_node->name.ascii, gpe_number));
		}
	}

	if (local_gpe_event_info.flags & ACPI_EVENT_LEVEL_TRIGGERED) {
		/*
		 * GPE is level-triggered, we clear the GPE status bit after handling
		 * the event.
		 */
		status = acpi_hw_clear_gpe (&local_gpe_event_info);
		if (ACPI_FAILURE (status)) {
			return_VOID;
		}
	}

	/* Enable this GPE */

	(void) acpi_hw_enable_gpe (&local_gpe_event_info);
	return_VOID;
}
Esempio n. 13
0
acpi_status
acpi_ns_evaluate_relative (
	acpi_namespace_node     *handle,
	NATIVE_CHAR             *pathname,
	acpi_operand_object     **params,
	acpi_operand_object     **return_object)
{
	acpi_namespace_node     *prefix_node;
	acpi_status             status;
	acpi_namespace_node     *node = NULL;
	NATIVE_CHAR             *internal_path = NULL;
	acpi_generic_state      scope_info;


	FUNCTION_TRACE ("Ns_evaluate_relative");


	/*
	 * Must have a valid object handle
	 */
	if (!handle) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	/* Build an internal name string for the method */

	status = acpi_ns_internalize_name (pathname, &internal_path);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Get the prefix handle and Node */

	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);

	prefix_node = acpi_ns_map_handle_to_node (handle);
	if (!prefix_node) {
		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
		status = AE_BAD_PARAMETER;
		goto cleanup;
	}

	/* Lookup the name in the namespace */

	scope_info.scope.node = prefix_node;
	status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY,
			 IMODE_EXECUTE, NS_NO_UPSEARCH, NULL,
			 &node);

	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);

	if (ACPI_FAILURE (status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object [%s] not found [%s]\n",
			pathname, acpi_format_exception (status)));
		goto cleanup;
	}

	/*
	 * Now that we have a handle to the object, we can attempt
	 * to evaluate it.
	 */
	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s [%p] Value %p\n",
		pathname, node, node->object));

	status = acpi_ns_evaluate_by_handle (node, params, return_object);

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "*** Completed eval of object %s ***\n",
		pathname));

cleanup:

	ACPI_MEM_FREE (internal_path);
	return_ACPI_STATUS (status);
}