|
@@ -44,19 +44,10 @@
|
|
#include <acpi/acpi.h>
|
|
#include <acpi/acpi.h>
|
|
#include "accommon.h"
|
|
#include "accommon.h"
|
|
#include "acnamesp.h"
|
|
#include "acnamesp.h"
|
|
-#include "acinterp.h"
|
|
|
|
|
|
|
|
#define _COMPONENT ACPI_UTILITIES
|
|
#define _COMPONENT ACPI_UTILITIES
|
|
ACPI_MODULE_NAME("uteval")
|
|
ACPI_MODULE_NAME("uteval")
|
|
|
|
|
|
-/* Local prototypes */
|
|
|
|
-static void
|
|
|
|
-acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length);
|
|
|
|
-
|
|
|
|
-static acpi_status
|
|
|
|
-acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
|
|
|
|
- struct acpi_compatible_id *one_cid);
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Strings supported by the _OSI predefined (internal) method.
|
|
* Strings supported by the _OSI predefined (internal) method.
|
|
*
|
|
*
|
|
@@ -213,7 +204,7 @@ acpi_status acpi_osi_invalidate(char *interface)
|
|
* RETURN: Status
|
|
* RETURN: Status
|
|
*
|
|
*
|
|
* DESCRIPTION: Evaluates a namespace object and verifies the type of the
|
|
* DESCRIPTION: Evaluates a namespace object and verifies the type of the
|
|
- * return object. Common code that simplifies accessing objects
|
|
|
|
|
|
+ * return object. Common code that simplifies accessing objects
|
|
* that have required return objects of fixed types.
|
|
* that have required return objects of fixed types.
|
|
*
|
|
*
|
|
* NOTE: Internal function, no parameter validation
|
|
* NOTE: Internal function, no parameter validation
|
|
@@ -298,7 +289,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
|
|
|
|
|
|
if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
|
|
if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
|
|
/*
|
|
/*
|
|
- * We received a return object, but one was not expected. This can
|
|
|
|
|
|
+ * We received a return object, but one was not expected. This can
|
|
* happen frequently if the "implicit return" feature is enabled.
|
|
* happen frequently if the "implicit return" feature is enabled.
|
|
* Just delete the return object and return AE_OK.
|
|
* Just delete the return object and return AE_OK.
|
|
*/
|
|
*/
|
|
@@ -340,12 +331,12 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
|
|
*
|
|
*
|
|
* PARAMETERS: object_name - Object name to be evaluated
|
|
* PARAMETERS: object_name - Object name to be evaluated
|
|
* device_node - Node for the device
|
|
* device_node - Node for the device
|
|
- * Address - Where the value is returned
|
|
|
|
|
|
+ * Value - Where the value is returned
|
|
*
|
|
*
|
|
* RETURN: Status
|
|
* RETURN: Status
|
|
*
|
|
*
|
|
* DESCRIPTION: Evaluates a numeric namespace object for a selected device
|
|
* DESCRIPTION: Evaluates a numeric namespace object for a selected device
|
|
- * and stores result in *Address.
|
|
|
|
|
|
+ * and stores result in *Value.
|
|
*
|
|
*
|
|
* NOTE: Internal function, no parameter validation
|
|
* NOTE: Internal function, no parameter validation
|
|
*
|
|
*
|
|
@@ -354,7 +345,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
|
|
acpi_status
|
|
acpi_status
|
|
acpi_ut_evaluate_numeric_object(char *object_name,
|
|
acpi_ut_evaluate_numeric_object(char *object_name,
|
|
struct acpi_namespace_node *device_node,
|
|
struct acpi_namespace_node *device_node,
|
|
- acpi_integer * address)
|
|
|
|
|
|
+ acpi_integer *value)
|
|
{
|
|
{
|
|
union acpi_operand_object *obj_desc;
|
|
union acpi_operand_object *obj_desc;
|
|
acpi_status status;
|
|
acpi_status status;
|
|
@@ -369,295 +360,7 @@ acpi_ut_evaluate_numeric_object(char *object_name,
|
|
|
|
|
|
/* Get the returned Integer */
|
|
/* Get the returned Integer */
|
|
|
|
|
|
- *address = obj_desc->integer.value;
|
|
|
|
-
|
|
|
|
- /* On exit, we must delete the return object */
|
|
|
|
-
|
|
|
|
- acpi_ut_remove_reference(obj_desc);
|
|
|
|
- return_ACPI_STATUS(status);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*******************************************************************************
|
|
|
|
- *
|
|
|
|
- * FUNCTION: acpi_ut_copy_id_string
|
|
|
|
- *
|
|
|
|
- * PARAMETERS: Destination - Where to copy the string
|
|
|
|
- * Source - Source string
|
|
|
|
- * max_length - Length of the destination buffer
|
|
|
|
- *
|
|
|
|
- * RETURN: None
|
|
|
|
- *
|
|
|
|
- * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
|
|
|
|
- * Performs removal of a leading asterisk if present -- workaround
|
|
|
|
- * for a known issue on a bunch of machines.
|
|
|
|
- *
|
|
|
|
- ******************************************************************************/
|
|
|
|
-
|
|
|
|
-static void
|
|
|
|
-acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
|
|
|
|
-{
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Workaround for ID strings that have a leading asterisk. This construct
|
|
|
|
- * is not allowed by the ACPI specification (ID strings must be
|
|
|
|
- * alphanumeric), but enough existing machines have this embedded in their
|
|
|
|
- * ID strings that the following code is useful.
|
|
|
|
- */
|
|
|
|
- if (*source == '*') {
|
|
|
|
- source++;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Do the actual copy */
|
|
|
|
-
|
|
|
|
- ACPI_STRNCPY(destination, source, max_length);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*******************************************************************************
|
|
|
|
- *
|
|
|
|
- * FUNCTION: acpi_ut_execute_HID
|
|
|
|
- *
|
|
|
|
- * PARAMETERS: device_node - Node for the device
|
|
|
|
- * Hid - Where the HID is returned
|
|
|
|
- *
|
|
|
|
- * RETURN: Status
|
|
|
|
- *
|
|
|
|
- * DESCRIPTION: Executes the _HID control method that returns the hardware
|
|
|
|
- * ID of the device.
|
|
|
|
- *
|
|
|
|
- * NOTE: Internal function, no parameter validation
|
|
|
|
- *
|
|
|
|
- ******************************************************************************/
|
|
|
|
-
|
|
|
|
-acpi_status
|
|
|
|
-acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
|
|
|
|
- struct acpica_device_id *hid)
|
|
|
|
-{
|
|
|
|
- union acpi_operand_object *obj_desc;
|
|
|
|
- acpi_status status;
|
|
|
|
-
|
|
|
|
- ACPI_FUNCTION_TRACE(ut_execute_HID);
|
|
|
|
-
|
|
|
|
- status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
|
|
|
|
- ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
|
|
|
|
- &obj_desc);
|
|
|
|
- if (ACPI_FAILURE(status)) {
|
|
|
|
- return_ACPI_STATUS(status);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
|
|
|
|
-
|
|
|
|
- /* Convert the Numeric HID to string */
|
|
|
|
-
|
|
|
|
- acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
|
|
|
|
- hid->value);
|
|
|
|
- } else {
|
|
|
|
- /* Copy the String HID from the returned object */
|
|
|
|
-
|
|
|
|
- acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer,
|
|
|
|
- sizeof(hid->value));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* On exit, we must delete the return object */
|
|
|
|
-
|
|
|
|
- acpi_ut_remove_reference(obj_desc);
|
|
|
|
- return_ACPI_STATUS(status);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*******************************************************************************
|
|
|
|
- *
|
|
|
|
- * FUNCTION: acpi_ut_translate_one_cid
|
|
|
|
- *
|
|
|
|
- * PARAMETERS: obj_desc - _CID object, must be integer or string
|
|
|
|
- * one_cid - Where the CID string is returned
|
|
|
|
- *
|
|
|
|
- * RETURN: Status
|
|
|
|
- *
|
|
|
|
- * DESCRIPTION: Return a numeric or string _CID value as a string.
|
|
|
|
- * (Compatible ID)
|
|
|
|
- *
|
|
|
|
- * NOTE: Assumes a maximum _CID string length of
|
|
|
|
- * ACPI_MAX_CID_LENGTH.
|
|
|
|
- *
|
|
|
|
- ******************************************************************************/
|
|
|
|
-
|
|
|
|
-static acpi_status
|
|
|
|
-acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
|
|
|
|
- struct acpi_compatible_id *one_cid)
|
|
|
|
-{
|
|
|
|
-
|
|
|
|
- switch (obj_desc->common.type) {
|
|
|
|
- case ACPI_TYPE_INTEGER:
|
|
|
|
-
|
|
|
|
- /* Convert the Numeric CID to string */
|
|
|
|
-
|
|
|
|
- acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
|
|
|
|
- one_cid->value);
|
|
|
|
- return (AE_OK);
|
|
|
|
-
|
|
|
|
- case ACPI_TYPE_STRING:
|
|
|
|
-
|
|
|
|
- if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
|
|
|
|
- return (AE_AML_STRING_LIMIT);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Copy the String CID from the returned object */
|
|
|
|
-
|
|
|
|
- acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer,
|
|
|
|
- ACPI_MAX_CID_LENGTH);
|
|
|
|
- return (AE_OK);
|
|
|
|
-
|
|
|
|
- default:
|
|
|
|
-
|
|
|
|
- return (AE_TYPE);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*******************************************************************************
|
|
|
|
- *
|
|
|
|
- * FUNCTION: acpi_ut_execute_CID
|
|
|
|
- *
|
|
|
|
- * PARAMETERS: device_node - Node for the device
|
|
|
|
- * return_cid_list - Where the CID list is returned
|
|
|
|
- *
|
|
|
|
- * RETURN: Status
|
|
|
|
- *
|
|
|
|
- * DESCRIPTION: Executes the _CID control method that returns one or more
|
|
|
|
- * compatible hardware IDs for the device.
|
|
|
|
- *
|
|
|
|
- * NOTE: Internal function, no parameter validation
|
|
|
|
- *
|
|
|
|
- ******************************************************************************/
|
|
|
|
-
|
|
|
|
-acpi_status
|
|
|
|
-acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
|
|
|
|
- struct acpi_compatible_id_list ** return_cid_list)
|
|
|
|
-{
|
|
|
|
- union acpi_operand_object *obj_desc;
|
|
|
|
- acpi_status status;
|
|
|
|
- u32 count;
|
|
|
|
- u32 size;
|
|
|
|
- struct acpi_compatible_id_list *cid_list;
|
|
|
|
- u32 i;
|
|
|
|
-
|
|
|
|
- ACPI_FUNCTION_TRACE(ut_execute_CID);
|
|
|
|
-
|
|
|
|
- /* Evaluate the _CID method for this device */
|
|
|
|
-
|
|
|
|
- status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
|
|
|
|
- ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
|
|
|
|
- | ACPI_BTYPE_PACKAGE, &obj_desc);
|
|
|
|
- if (ACPI_FAILURE(status)) {
|
|
|
|
- return_ACPI_STATUS(status);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Get the number of _CIDs returned */
|
|
|
|
-
|
|
|
|
- count = 1;
|
|
|
|
- if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
|
|
|
|
- count = obj_desc->package.count;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Allocate a worst-case buffer for the _CIDs */
|
|
|
|
-
|
|
|
|
- size = (((count - 1) * sizeof(struct acpi_compatible_id)) +
|
|
|
|
- sizeof(struct acpi_compatible_id_list));
|
|
|
|
-
|
|
|
|
- cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
|
|
|
|
- if (!cid_list) {
|
|
|
|
- return_ACPI_STATUS(AE_NO_MEMORY);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Init CID list */
|
|
|
|
-
|
|
|
|
- cid_list->count = count;
|
|
|
|
- cid_list->size = size;
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * A _CID can return either a single compatible ID or a package of
|
|
|
|
- * compatible IDs. Each compatible ID can be one of the following:
|
|
|
|
- * 1) Integer (32 bit compressed EISA ID) or
|
|
|
|
- * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- /* The _CID object can be either a single CID or a package (list) of CIDs */
|
|
|
|
-
|
|
|
|
- if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
|
|
|
|
-
|
|
|
|
- /* Translate each package element */
|
|
|
|
-
|
|
|
|
- for (i = 0; i < count; i++) {
|
|
|
|
- status =
|
|
|
|
- acpi_ut_translate_one_cid(obj_desc->package.
|
|
|
|
- elements[i],
|
|
|
|
- &cid_list->id[i]);
|
|
|
|
- if (ACPI_FAILURE(status)) {
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- /* Only one CID, translate to a string */
|
|
|
|
-
|
|
|
|
- status = acpi_ut_translate_one_cid(obj_desc, cid_list->id);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Cleanup on error */
|
|
|
|
-
|
|
|
|
- if (ACPI_FAILURE(status)) {
|
|
|
|
- ACPI_FREE(cid_list);
|
|
|
|
- } else {
|
|
|
|
- *return_cid_list = cid_list;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* On exit, we must delete the _CID return object */
|
|
|
|
-
|
|
|
|
- acpi_ut_remove_reference(obj_desc);
|
|
|
|
- return_ACPI_STATUS(status);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*******************************************************************************
|
|
|
|
- *
|
|
|
|
- * FUNCTION: acpi_ut_execute_UID
|
|
|
|
- *
|
|
|
|
- * PARAMETERS: device_node - Node for the device
|
|
|
|
- * Uid - Where the UID is returned
|
|
|
|
- *
|
|
|
|
- * RETURN: Status
|
|
|
|
- *
|
|
|
|
- * DESCRIPTION: Executes the _UID control method that returns the hardware
|
|
|
|
- * ID of the device.
|
|
|
|
- *
|
|
|
|
- * NOTE: Internal function, no parameter validation
|
|
|
|
- *
|
|
|
|
- ******************************************************************************/
|
|
|
|
-
|
|
|
|
-acpi_status
|
|
|
|
-acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
|
|
|
|
- struct acpica_device_id *uid)
|
|
|
|
-{
|
|
|
|
- union acpi_operand_object *obj_desc;
|
|
|
|
- acpi_status status;
|
|
|
|
-
|
|
|
|
- ACPI_FUNCTION_TRACE(ut_execute_UID);
|
|
|
|
-
|
|
|
|
- status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
|
|
|
|
- ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
|
|
|
|
- &obj_desc);
|
|
|
|
- if (ACPI_FAILURE(status)) {
|
|
|
|
- return_ACPI_STATUS(status);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
|
|
|
|
-
|
|
|
|
- /* Convert the Numeric UID to string */
|
|
|
|
-
|
|
|
|
- acpi_ex_unsigned_integer_to_string(obj_desc->integer.value,
|
|
|
|
- uid->value);
|
|
|
|
- } else {
|
|
|
|
- /* Copy the String UID from the returned object */
|
|
|
|
-
|
|
|
|
- acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer,
|
|
|
|
- sizeof(uid->value));
|
|
|
|
- }
|
|
|
|
|
|
+ *value = obj_desc->integer.value;
|
|
|
|
|
|
/* On exit, we must delete the return object */
|
|
/* On exit, we must delete the return object */
|
|
|
|
|
|
@@ -716,60 +419,64 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
|
|
|
|
|
|
/*******************************************************************************
|
|
/*******************************************************************************
|
|
*
|
|
*
|
|
- * FUNCTION: acpi_ut_execute_Sxds
|
|
|
|
|
|
+ * FUNCTION: acpi_ut_execute_power_methods
|
|
*
|
|
*
|
|
* PARAMETERS: device_node - Node for the device
|
|
* PARAMETERS: device_node - Node for the device
|
|
- * Flags - Where the status flags are returned
|
|
|
|
|
|
+ * method_names - Array of power method names
|
|
|
|
+ * method_count - Number of methods to execute
|
|
|
|
+ * out_values - Where the power method values are returned
|
|
*
|
|
*
|
|
- * RETURN: Status
|
|
|
|
|
|
+ * RETURN: Status, out_values
|
|
*
|
|
*
|
|
- * DESCRIPTION: Executes _STA for selected device and stores results in
|
|
|
|
- * *Flags.
|
|
|
|
|
|
+ * DESCRIPTION: Executes the specified power methods for the device and returns
|
|
|
|
+ * the result(s).
|
|
*
|
|
*
|
|
* NOTE: Internal function, no parameter validation
|
|
* NOTE: Internal function, no parameter validation
|
|
*
|
|
*
|
|
- ******************************************************************************/
|
|
|
|
|
|
+******************************************************************************/
|
|
|
|
|
|
acpi_status
|
|
acpi_status
|
|
-acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest)
|
|
|
|
|
|
+acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node,
|
|
|
|
+ const char **method_names,
|
|
|
|
+ u8 method_count, u8 *out_values)
|
|
{
|
|
{
|
|
union acpi_operand_object *obj_desc;
|
|
union acpi_operand_object *obj_desc;
|
|
acpi_status status;
|
|
acpi_status status;
|
|
|
|
+ acpi_status final_status = AE_NOT_FOUND;
|
|
u32 i;
|
|
u32 i;
|
|
|
|
|
|
- ACPI_FUNCTION_TRACE(ut_execute_sxds);
|
|
|
|
|
|
+ ACPI_FUNCTION_TRACE(ut_execute_power_methods);
|
|
|
|
|
|
- for (i = 0; i < 4; i++) {
|
|
|
|
- highest[i] = 0xFF;
|
|
|
|
|
|
+ for (i = 0; i < method_count; i++) {
|
|
|
|
+ /*
|
|
|
|
+ * Execute the power method (_sx_d or _sx_w). The only allowable
|
|
|
|
+ * return type is an Integer.
|
|
|
|
+ */
|
|
status = acpi_ut_evaluate_object(device_node,
|
|
status = acpi_ut_evaluate_object(device_node,
|
|
ACPI_CAST_PTR(char,
|
|
ACPI_CAST_PTR(char,
|
|
- acpi_gbl_highest_dstate_names
|
|
|
|
- [i]),
|
|
|
|
|
|
+ method_names[i]),
|
|
ACPI_BTYPE_INTEGER, &obj_desc);
|
|
ACPI_BTYPE_INTEGER, &obj_desc);
|
|
- if (ACPI_FAILURE(status)) {
|
|
|
|
- if (status != AE_NOT_FOUND) {
|
|
|
|
- ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
|
|
|
- "%s on Device %4.4s, %s\n",
|
|
|
|
- ACPI_CAST_PTR(char,
|
|
|
|
- acpi_gbl_highest_dstate_names
|
|
|
|
- [i]),
|
|
|
|
- acpi_ut_get_node_name
|
|
|
|
- (device_node),
|
|
|
|
- acpi_format_exception
|
|
|
|
- (status)));
|
|
|
|
-
|
|
|
|
- return_ACPI_STATUS(status);
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- /* Extract the Dstate value */
|
|
|
|
-
|
|
|
|
- highest[i] = (u8) obj_desc->integer.value;
|
|
|
|
|
|
+ if (ACPI_SUCCESS(status)) {
|
|
|
|
+ out_values[i] = (u8)obj_desc->integer.value;
|
|
|
|
|
|
/* Delete the return object */
|
|
/* Delete the return object */
|
|
|
|
|
|
acpi_ut_remove_reference(obj_desc);
|
|
acpi_ut_remove_reference(obj_desc);
|
|
|
|
+ final_status = AE_OK; /* At least one value is valid */
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ out_values[i] = ACPI_UINT8_MAX;
|
|
|
|
+ if (status == AE_NOT_FOUND) {
|
|
|
|
+ continue; /* Ignore if not found */
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
|
|
|
+ "Failed %s on Device %4.4s, %s\n",
|
|
|
|
+ ACPI_CAST_PTR(char, method_names[i]),
|
|
|
|
+ acpi_ut_get_node_name(device_node),
|
|
|
|
+ acpi_format_exception(status)));
|
|
}
|
|
}
|
|
|
|
|
|
- return_ACPI_STATUS(AE_OK);
|
|
|
|
|
|
+ return_ACPI_STATUS(final_status);
|
|
}
|
|
}
|