示例#1
0
ACPI_STATUS
acpi_cm_execute_UID (
	ACPI_NAMESPACE_NODE     *device_node,
	DEVICE_ID               *uid)
{
	ACPI_OPERAND_OBJECT     *obj_desc;
	ACPI_STATUS             status;


	/* Execute the method */

	status = acpi_ns_evaluate_relative (device_node,
			 METHOD_NAME__UID, NULL, &obj_desc);
	if (ACPI_FAILURE (status)) {


		return (status);
	}

	/* Did we get a return object? */

	if (!obj_desc) {
		return (AE_TYPE);
	}

	/*
	 *  A _UID can return either a Number (32 bit compressed EISA ID) or
	 *  a string
	 */

	if ((obj_desc->common.type != ACPI_TYPE_NUMBER) &&
		(obj_desc->common.type != ACPI_TYPE_STRING))
	{
		status = AE_TYPE;
	}

	else {
		if (obj_desc->common.type == ACPI_TYPE_NUMBER) {
			/* Convert the Numeric UID to string */

			acpi_aml_unsigned_integer_to_string (obj_desc->number.value, uid->buffer);
		}

		else {
			/* Copy the String UID from the returned object */

			STRNCPY(uid->buffer, obj_desc->string.pointer, sizeof(uid->buffer));
		}
	}


	/* On exit, we must delete the return object */

	acpi_cm_remove_reference (obj_desc);

	return (status);
}
示例#2
0
ACPI_STATUS
acpi_cm_execute_STA (
	ACPI_NAMESPACE_NODE     *device_node,
	u32                     *flags)
{
	ACPI_OPERAND_OBJECT     *obj_desc;
	ACPI_STATUS             status;


	/* Execute the method */

	status = acpi_ns_evaluate_relative (device_node,
			 METHOD_NAME__STA, NULL, &obj_desc);
	if (AE_NOT_FOUND == status) {
		*flags = 0x0F;
		status = AE_OK;
	}


	else /* success */ {
		/* Did we get a return object? */

		if (!obj_desc) {
			return (AE_TYPE);
		}

		/* Is the return object of the correct type? */

		if (obj_desc->common.type != ACPI_TYPE_NUMBER) {
			status = AE_TYPE;
		}

		else {
			/* Extract the status flags */

			*flags = (u32) obj_desc->number.value;
		}

		/* On exit, we must delete the return object */

		acpi_cm_remove_reference (obj_desc);
	}

	return (status);
}
示例#3
0
ACPI_STATUS
acpi_cm_evaluate_numeric_object (
	NATIVE_CHAR             *object_name,
	ACPI_NAMESPACE_NODE     *device_node,
	ACPI_INTEGER            *address)
{
	ACPI_OPERAND_OBJECT     *obj_desc;
	ACPI_STATUS             status;


	/* Execute the method */

	status = acpi_ns_evaluate_relative (device_node, object_name, NULL, &obj_desc);
	if (ACPI_FAILURE (status)) {

		return (status);
	}


	/* Did we get a return object? */

	if (!obj_desc) {
		return (AE_TYPE);
	}

	/* Is the return object of the correct type? */

	if (obj_desc->common.type != ACPI_TYPE_NUMBER) {
		status = AE_TYPE;
	}
	else {
		/*
		 * Since the structure is a union, setting any field will set all
		 * of the variables in the union
		 */
		*address = obj_desc->number.value;
	}

	/* On exit, we must delete the return object */

	acpi_cm_remove_reference (obj_desc);

	return (status);
}
示例#4
0
文件: nsinit.c 项目: TitaniumBoy/lin
acpi_status
acpi_ns_init_one_device (
	acpi_handle             obj_handle,
	u32                     nesting_level,
	void                    *context,
	void                    **return_value)
{
	acpi_status             status;
	acpi_namespace_node    *node;
	u32                     flags;
	acpi_device_walk_info  *info = (acpi_device_walk_info *) context;


	FUNCTION_TRACE ("Ns_init_one_device");


	if (!(acpi_dbg_level & ACPI_LV_INIT)) {
		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "."));
	}

	info->device_count++;

	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);

	node = acpi_ns_map_handle_to_node (obj_handle);
	if (!node) {
		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
		return (AE_BAD_PARAMETER);
	}

	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);

	/*
	 * Run _STA to determine if we can run _INI on the device.
	 */
	DEBUG_EXEC (acpi_ut_display_init_pathname (node, "_STA [Method]"));
	status = acpi_ut_execute_STA (node, &flags);
	if (ACPI_FAILURE (status)) {
		/* Ignore error and move on to next device */

		return_ACPI_STATUS (AE_OK);
	}

	info->num_STA++;

	if (!(flags & 0x01)) {
		/* don't look at children of a not present device */

		return_ACPI_STATUS(AE_CTRL_DEPTH);
	}


	/*
	 * The device is present. Run _INI.
	 */
	DEBUG_EXEC (acpi_ut_display_init_pathname (obj_handle, "_INI [Method]"));
	status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL);
	if (AE_NOT_FOUND == status) {
		/* No _INI means device requires no initialization */

		status = AE_OK;
	}

	else if (ACPI_FAILURE (status)) {
		/* Ignore error and move on to next device */

#ifdef ACPI_DEBUG
		NATIVE_CHAR *scope_name = acpi_ns_get_table_pathname (obj_handle);

		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%s._INI failed: %s\n",
				scope_name, acpi_format_exception (status)));

		ACPI_MEM_FREE (scope_name);
#endif
	}

	else {
		/* Count of successful INIs */

		info->num_INI++;
	}

	return_ACPI_STATUS (AE_OK);
}
示例#5
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);
}
示例#6
0
acpi_status
acpi_ut_evaluate_object (
	struct acpi_namespace_node      *prefix_node,
	char                            *path,
	u32                             expected_return_btypes,
	union acpi_operand_object       **return_desc)
{
	struct acpi_parameter_info      info;
	acpi_status                     status;
	u32                             return_btype;


	ACPI_FUNCTION_TRACE ("ut_evaluate_object");


	info.node = prefix_node;
	info.parameters = NULL;
	info.parameter_type = ACPI_PARAM_ARGS;

	/* Evaluate the object/method */

	status = acpi_ns_evaluate_relative (path, &info);
	if (ACPI_FAILURE (status)) {
		if (status == AE_NOT_FOUND) {
			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
				acpi_ut_get_node_name (prefix_node), path));
		}
		else {
			ACPI_REPORT_METHOD_ERROR ("Method execution failed",
				prefix_node, path, status);
		}

		return_ACPI_STATUS (status);
	}

	/* Did we get a return object? */

	if (!info.return_object) {
		if (expected_return_btypes) {
			ACPI_REPORT_METHOD_ERROR ("No object was returned from",
				prefix_node, path, AE_NOT_EXIST);

			return_ACPI_STATUS (AE_NOT_EXIST);
		}

		return_ACPI_STATUS (AE_OK);
	}

	/* Map the return object type to the bitmapped type */

	switch (ACPI_GET_OBJECT_TYPE (info.return_object)) {
	case ACPI_TYPE_INTEGER:
		return_btype = ACPI_BTYPE_INTEGER;
		break;

	case ACPI_TYPE_BUFFER:
		return_btype = ACPI_BTYPE_BUFFER;
		break;

	case ACPI_TYPE_STRING:
		return_btype = ACPI_BTYPE_STRING;
		break;

	case ACPI_TYPE_PACKAGE:
		return_btype = ACPI_BTYPE_PACKAGE;
		break;

	default:
		return_btype = 0;
		break;
	}

	/* Is the return object one of the expected types? */

	if (!(expected_return_btypes & return_btype)) {
		ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect",
			prefix_node, path, AE_TYPE);

		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
			"Type returned from %s was incorrect: %X\n",
			path, ACPI_GET_OBJECT_TYPE (info.return_object)));

		/* On error exit, we must delete the return object */

		acpi_ut_remove_reference (info.return_object);
		return_ACPI_STATUS (AE_TYPE);
	}

	/* Object type is OK, return it */

	*return_desc = info.return_object;
	return_ACPI_STATUS (AE_OK);
}
示例#7
0
acpi_status
acpi_rs_get_prt_method_data (
	acpi_handle             handle,
	acpi_buffer             *ret_buffer)
{
	acpi_operand_object     *ret_obj;
	acpi_status             status;
	u32                     buffer_space_needed;


	FUNCTION_TRACE ("Rs_get_prt_method_data");


	/* already validated params, so we won't repeat here */

	buffer_space_needed = ret_buffer->length;

	/*
	 *  Execute the method, no parameters
	 */
	status = acpi_ns_evaluate_relative (handle, "_PRT", NULL, &ret_obj);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	if (!ret_obj) {
		/* Return object is required */

		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _PRT\n"));
		return_ACPI_STATUS (AE_TYPE);
	}


	/*
	 * The return object will be a package, so check the
	 *  parameters.  If the return object is not a package,
	 *  then the underlying AML code is corrupt or improperly
	 *  written.
	 */
	if (ACPI_TYPE_PACKAGE != ret_obj->common.type) {
		status = AE_AML_OPERAND_TYPE;
		goto cleanup;
	}

	/*
	 * Make the call to create a resource linked list from the
	 *  byte stream buffer that comes back from the _CRS method
	 *  execution.
	 */
	status = acpi_rs_create_pci_routing_table (ret_obj, ret_buffer->pointer,
			  &buffer_space_needed);

	/*
	 * Tell the user how much of the buffer we have used or is needed
	 *  and return the final status.
	 */
	ret_buffer->length = buffer_space_needed;


	/* On exit, we must delete the object returned by evaluate_object */

cleanup:

	acpi_ut_remove_reference (ret_obj);
	return_ACPI_STATUS (status);
}
示例#8
0
acpi_status
acpi_rs_set_srs_method_data (
	acpi_handle             handle,
	acpi_buffer             *in_buffer)
{
	acpi_operand_object     *params[2];
	acpi_status             status;
	u8                      *byte_stream = NULL;
	u32                     buffer_size_needed = 0;


	FUNCTION_TRACE ("Rs_set_srs_method_data");


	/* already validated params, so we won't repeat here */

	/*
	 * The In_buffer parameter will point to a linked list of
	 * resource parameters.  It needs to be formatted into a
	 * byte stream to be sent in as an input parameter.
	 */
	buffer_size_needed = 0;

	/*
	 * First call is to get the buffer size needed
	 */
	status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream,
			 &buffer_size_needed);
	/*
	 * We expect a return of AE_BUFFER_OVERFLOW
	 * if not, exit with the error
	 */
	if (AE_BUFFER_OVERFLOW != status) {
		return_ACPI_STATUS (status);
	}

	/*
	 * Allocate the buffer needed
	 */
	byte_stream = ACPI_MEM_CALLOCATE (buffer_size_needed);
	if (NULL == byte_stream) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/*
	 * Now call to convert the linked list into a byte stream
	 */
	status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream,
			 &buffer_size_needed);
	if (ACPI_FAILURE (status)) {
		goto cleanup;
	}

	/*
	 * Init the param object
	 */
	params[0] = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
	if (!params[0]) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}
	params [1] = NULL;

	/*
	 *  Set up the parameter object
	 */
	params[0]->buffer.length  = buffer_size_needed;
	params[0]->buffer.pointer = byte_stream;

	/*
	 * Execute the method, no return value
	 */
	status = acpi_ns_evaluate_relative (handle, "_SRS", params, NULL);
	acpi_ut_remove_reference (params[0]);

	/*
	 * Clean up and return the status from Acpi_ns_evaluate_relative
	 */
cleanup:

	return_ACPI_STATUS (status);
}
示例#9
0
static acpi_status
acpi_ns_init_one_device(acpi_handle obj_handle,
			u32 nesting_level, void *context, void **return_value)
{
	struct acpi_device_walk_info *info =
	    (struct acpi_device_walk_info *)context;
	struct acpi_parameter_info pinfo;
	u32 flags;
	acpi_status status;

	ACPI_FUNCTION_TRACE("ns_init_one_device");

	pinfo.parameters = NULL;
	pinfo.parameter_type = ACPI_PARAM_ARGS;

	pinfo.node = acpi_ns_map_handle_to_node(obj_handle);
	if (!pinfo.node) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	/*
	 * We will run _STA/_INI on Devices, Processors and thermal_zones only
	 */
	if ((pinfo.node->type != ACPI_TYPE_DEVICE) &&
	    (pinfo.node->type != ACPI_TYPE_PROCESSOR) &&
	    (pinfo.node->type != ACPI_TYPE_THERMAL)) {
		return_ACPI_STATUS(AE_OK);
	}

	if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) &&
	    (!(acpi_dbg_level & ACPI_LV_INFO))) {
		ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
	}

	info->device_count++;

	/*
	 * Run _STA to determine if we can run _INI on the device.
	 */
	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD,
						      pinfo.node,
						      METHOD_NAME__STA));
	status = acpi_ut_execute_STA(pinfo.node, &flags);

	if (ACPI_FAILURE(status)) {
		if (pinfo.node->type == ACPI_TYPE_DEVICE) {
			/* Ignore error and move on to next device */

			return_ACPI_STATUS(AE_OK);
		}

		/* _STA is not required for Processor or thermal_zone objects */
	} else {
		info->num_STA++;

		if (!(flags & 0x01)) {
			/* Don't look at children of a not present device */

			return_ACPI_STATUS(AE_CTRL_DEPTH);
		}
	}

	/*
	 * The device is present. Run _INI.
	 */
	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD,
						      pinfo.node,
						      METHOD_NAME__INI));
	status = acpi_ns_evaluate_relative(METHOD_NAME__INI, &pinfo);
	if (ACPI_FAILURE(status)) {
		/* No _INI (AE_NOT_FOUND) means device requires no initialization */

		if (status != AE_NOT_FOUND) {
			/* Ignore error and move on to next device */

#ifdef ACPI_DEBUG_OUTPUT
			char *scope_name =
			    acpi_ns_get_external_pathname(pinfo.node);

			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "%s._INI failed: %s\n",
					  scope_name,
					  acpi_format_exception(status)));

			ACPI_MEM_FREE(scope_name);
#endif
		}

		status = AE_OK;
	} else {
		/* Delete any return object (especially if implicit_return is enabled) */

		if (pinfo.return_object) {
			acpi_ut_remove_reference(pinfo.return_object);
		}

		/* Count of successful INIs */

		info->num_INI++;
	}

	if (acpi_gbl_init_handler) {
		/* External initialization handler is present, call it */

		status =
		    acpi_gbl_init_handler(pinfo.node, ACPI_INIT_DEVICE_INI);
	}

	return_ACPI_STATUS(status);
}
示例#10
0
文件: nsxfobj.c 项目: davidbau/davej
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);
}
示例#11
0
ACPI_STATUS
acpi_ns_init_one_device (
	ACPI_HANDLE             obj_handle,
	u32                     nesting_level,
	void                    *context,
	void                    **return_value)
{
	ACPI_STATUS             status;
	ACPI_NAMESPACE_NODE    *node;
	u32                     flags;
	ACPI_DEVICE_WALK_INFO  *info = (ACPI_DEVICE_WALK_INFO *) context;


	info->device_count++;

	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);

	node = acpi_ns_convert_handle_to_entry (obj_handle);
	if (!node) {
		acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
		return (AE_BAD_PARAMETER);
	}

	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);

	/*
	 * Run _STA to determine if we can run _INI on the device.
	 */

	status = acpi_cm_execute_STA (node, &flags);
	if (ACPI_FAILURE (status)) {
		return (status);
	}

	info->num_STA++;

	if (!(flags & 0x01)) {
		/* don't look at children of a not present device */
		return(AE_CTRL_DEPTH);
	}

	/*
	 * The device is present. Run _INI.
	 */

	status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL);
	if (AE_NOT_FOUND == status) {
		/* No _INI means device requires no initialization */
		status = AE_OK;
	}

	else if (ACPI_FAILURE (status)) {
		return (status);
	}

	else {
		info->num_INI++;
	}

	return (status);
}