Commit 7b3b0219 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] ACPICA 20040220 from Bob Moore

Implemented execution of _SxD methods for Device objects in the
GetObjectInfo interface.

Fixed calls to _SST method to pass the correct arguments.

Added a call to _SST on wake to restore to "working" state.

Check for End-Of-Buffer failure case in the WalkResources interface.

Integrated fix for 64-bit alignment issue in acglobal.h by moving two
structures to the beginning of the file.

After wake, clear GPE status register(s) before enabling GPEs.

After wake, clear/enable power button.
(Perhaps we should clear/enable all fixed events upon wake.)

Fixed a couple of possible memory leaks in the Namespace manager.
parent daa74787
...@@ -528,6 +528,14 @@ acpi_hw_enable_non_wakeup_gpe_block ( ...@@ -528,6 +528,14 @@ acpi_hw_enable_non_wakeup_gpe_block (
/* Examine each GPE register within the block */ /* Examine each GPE register within the block */
for (i = 0; i < gpe_block->register_count; i++) { for (i = 0; i < gpe_block->register_count; i++) {
/* Clear the entire status register */
status = acpi_hw_low_level_write (8, 0xFF,
&gpe_block->register_info[i].status_address);
if (ACPI_FAILURE (status)) {
return (status);
}
/* /*
* We previously stored the enabled status of all GPEs. * We previously stored the enabled status of all GPEs.
* Blast them back in. * Blast them back in.
......
...@@ -152,11 +152,11 @@ acpi_get_sleep_type_data ( ...@@ -152,11 +152,11 @@ acpi_get_sleep_type_data (
/* /*
* Evaluate the namespace object containing the values for this state * Evaluate the namespace object containing the values for this state
*/ */
status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_db_sleep_states[sleep_state], status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_sleep_state_names[sleep_state],
NULL, &obj_desc); NULL, &obj_desc);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n", ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n",
acpi_format_exception (status), acpi_gbl_db_sleep_states[sleep_state])); acpi_format_exception (status), acpi_gbl_sleep_state_names[sleep_state]));
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -201,7 +201,7 @@ acpi_get_sleep_type_data ( ...@@ -201,7 +201,7 @@ acpi_get_sleep_type_data (
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating sleep_state [%s], bad Sleep object %p type %s\n", ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
acpi_gbl_db_sleep_states[sleep_state], obj_desc, acpi_ut_get_object_type_name (obj_desc))); acpi_gbl_sleep_state_names[sleep_state], obj_desc, acpi_ut_get_object_type_name (obj_desc)));
} }
acpi_ut_remove_reference (obj_desc); acpi_ut_remove_reference (obj_desc);
......
...@@ -48,6 +48,19 @@ ...@@ -48,6 +48,19 @@
ACPI_MODULE_NAME ("hwsleep") ACPI_MODULE_NAME ("hwsleep")
#define METHOD_NAME__BFS "\\_BFS"
#define METHOD_NAME__GTS "\\_GTS"
#define METHOD_NAME__PTS "\\_PTS"
#define METHOD_NAME__SST "\\_SI._SST"
#define METHOD_NAME__WAK "\\_WAK"
#define ACPI_SST_INDICATOR_OFF 0
#define ACPI_SST_WORKING 1
#define ACPI_SST_WAKING 2
#define ACPI_SST_SLEEPING 3
#define ACPI_SST_SLEEP_CONTEXT 4
/****************************************************************************** /******************************************************************************
* *
* FUNCTION: acpi_set_firmware_waking_vector * FUNCTION: acpi_set_firmware_waking_vector
...@@ -171,19 +184,41 @@ acpi_enter_sleep_state_prep ( ...@@ -171,19 +184,41 @@ acpi_enter_sleep_state_prep (
/* Run the _PTS and _GTS methods */ /* Run the _PTS and _GTS methods */
status = acpi_evaluate_object (NULL, "\\_PTS", &arg_list, NULL); status = acpi_evaluate_object (NULL, METHOD_NAME__PTS, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
status = acpi_evaluate_object (NULL, "\\_GTS", &arg_list, NULL); status = acpi_evaluate_object (NULL, METHOD_NAME__GTS, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
/* Setup the argument to _SST */
switch (sleep_state) {
case ACPI_STATE_S0:
arg.integer.value = ACPI_SST_WORKING;
break;
case ACPI_STATE_S1:
case ACPI_STATE_S2:
case ACPI_STATE_S3:
arg.integer.value = ACPI_SST_SLEEPING;
break;
case ACPI_STATE_S4:
arg.integer.value = ACPI_SST_SLEEP_CONTEXT;
break;
default:
arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is indicator off */
break;
}
/* Set the system indicators to show the desired sleep state. */ /* Set the system indicators to show the desired sleep state. */
status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL); status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
} }
...@@ -477,19 +512,19 @@ acpi_leave_sleep_state ( ...@@ -477,19 +512,19 @@ acpi_leave_sleep_state (
/* Ignore any errors from these methods */ /* Ignore any errors from these methods */
arg.integer.value = 0; arg.integer.value = ACPI_SST_WAKING;
status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL); status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
} }
arg.integer.value = sleep_state; arg.integer.value = sleep_state;
status = acpi_evaluate_object (NULL, "\\_BFS", &arg_list, NULL); status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status))); ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status)));
} }
status = acpi_evaluate_object (NULL, "\\_WAK", &arg_list, NULL); status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status))); ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status)));
} }
...@@ -501,8 +536,25 @@ acpi_leave_sleep_state ( ...@@ -501,8 +536,25 @@ acpi_leave_sleep_state (
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
/* Enable power button */
acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
1, ACPI_MTX_DO_NOT_LOCK);
acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
1, ACPI_MTX_DO_NOT_LOCK);
/* Enable BM arbitration */ /* Enable BM arbitration */
status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK); status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
arg.integer.value = ACPI_SST_WORKING;
status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
}
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -110,7 +110,7 @@ acpi_ns_evaluate_relative ( ...@@ -110,7 +110,7 @@ acpi_ns_evaluate_relative (
status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); goto cleanup;
} }
prefix_node = acpi_ns_map_handle_to_node (handle); prefix_node = acpi_ns_map_handle_to_node (handle);
...@@ -197,7 +197,7 @@ acpi_ns_evaluate_by_name ( ...@@ -197,7 +197,7 @@ acpi_ns_evaluate_by_name (
status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); goto cleanup;
} }
/* Lookup the name in the namespace */ /* Lookup the name in the namespace */
......
...@@ -918,7 +918,7 @@ acpi_ns_get_node_by_path ( ...@@ -918,7 +918,7 @@ acpi_ns_get_node_by_path (
status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); goto cleanup;
} }
/* Setup lookup scope (search starting point) */ /* Setup lookup scope (search starting point) */
...@@ -936,10 +936,10 @@ acpi_ns_get_node_by_path ( ...@@ -936,10 +936,10 @@ acpi_ns_get_node_by_path (
internal_path, acpi_format_exception (status))); internal_path, acpi_format_exception (status)));
} }
/* Cleanup */
(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
cleanup:
/* Cleanup */
if (internal_path) { if (internal_path) {
ACPI_MEM_FREE (internal_path); ACPI_MEM_FREE (internal_path);
} }
......
...@@ -326,6 +326,13 @@ acpi_get_object_info ( ...@@ -326,6 +326,13 @@ acpi_get_object_info (
info.valid |= ACPI_VALID_ADR; info.valid |= ACPI_VALID_ADR;
} }
/* Execute the Device._sx_d methods */
status = acpi_ut_execute_sxds (node, info.highest_dstates);
if (ACPI_SUCCESS (status)) {
info.valid |= ACPI_VALID_STA;
}
status = AE_OK; status = AE_OK;
} }
......
...@@ -239,6 +239,7 @@ acpi_walk_resources ( ...@@ -239,6 +239,7 @@ acpi_walk_resources (
acpi_status status; acpi_status status;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
struct acpi_resource *resource; struct acpi_resource *resource;
struct acpi_resource *buffer_end;
ACPI_FUNCTION_TRACE ("acpi_walk_resources"); ACPI_FUNCTION_TRACE ("acpi_walk_resources");
...@@ -255,7 +256,13 @@ acpi_walk_resources ( ...@@ -255,7 +256,13 @@ acpi_walk_resources (
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
resource = (struct acpi_resource *) buffer.pointer; /* Setup pointers */
resource = (struct acpi_resource *) buffer.pointer;
buffer_end = (struct acpi_resource *) ((u8 *) buffer.pointer + buffer.length);
/* Walk the resource list */
for (;;) { for (;;) {
if (!resource || resource->id == ACPI_RSTYPE_END_TAG) { if (!resource || resource->id == ACPI_RSTYPE_END_TAG) {
break; break;
...@@ -268,6 +275,7 @@ acpi_walk_resources ( ...@@ -268,6 +275,7 @@ acpi_walk_resources (
case AE_CTRL_DEPTH: case AE_CTRL_DEPTH:
/* Just keep going */ /* Just keep going */
status = AE_OK; status = AE_OK;
break; break;
...@@ -285,7 +293,15 @@ acpi_walk_resources ( ...@@ -285,7 +293,15 @@ acpi_walk_resources (
goto cleanup; goto cleanup;
} }
/* Get the next resource descriptor */
resource = ACPI_NEXT_RESOURCE (resource); resource = ACPI_NEXT_RESOURCE (resource);
/* Check for end-of-buffer */
if (resource >= buffer_end) {
goto cleanup;
}
} }
cleanup: cleanup:
......
...@@ -562,3 +562,63 @@ acpi_ut_execute_STA ( ...@@ -562,3 +562,63 @@ acpi_ut_execute_STA (
acpi_ut_remove_reference (obj_desc); acpi_ut_remove_reference (obj_desc);
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ut_execute_Sxds
*
* PARAMETERS: device_node - Node for the device
* *Flags - Where the status flags are returned
*
* RETURN: Status
*
* DESCRIPTION: Executes _STA for selected device and stores results in
* *Flags.
*
* NOTE: Internal function, no parameter validation
*
******************************************************************************/
acpi_status
acpi_ut_execute_sxds (
struct acpi_namespace_node *device_node,
u8 *highest)
{
union acpi_operand_object *obj_desc;
acpi_status status;
u32 i;
ACPI_FUNCTION_TRACE ("ut_execute_Sxds");
for (i = 0; i < 4; i++) {
highest[i] = 0xFF;
status = acpi_ut_evaluate_object (device_node,
(char *) acpi_gbl_highest_dstate_names[i],
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",
(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;
/* Delete the return object */
acpi_ut_remove_reference (obj_desc);
}
}
return_ACPI_STATUS (AE_OK);
}
...@@ -171,7 +171,7 @@ u8 acpi_gbl_shutdown = TRUE; ...@@ -171,7 +171,7 @@ u8 acpi_gbl_shutdown = TRUE;
const u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128}; const u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128};
const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT] = { const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = {
"\\_S0_", "\\_S0_",
"\\_S1_", "\\_S1_",
"\\_S2_", "\\_S2_",
...@@ -179,6 +179,11 @@ const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT ...@@ -179,6 +179,11 @@ const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT
"\\_S4_", "\\_S4_",
"\\_S5_"}; "\\_S5_"};
const char *acpi_gbl_highest_dstate_names[4] = {
"_S1D",
"_S2D",
"_S3D",
"_S4D"};
/****************************************************************************** /******************************************************************************
* *
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
/* Version string */ /* Version string */
#define ACPI_CA_VERSION 0x20040211 #define ACPI_CA_VERSION 0x20040220
/* Maximum objects in the various object caches */ /* Maximum objects in the various object caches */
......
...@@ -57,6 +57,12 @@ ...@@ -57,6 +57,12 @@
#define ACPI_EXTERN extern #define ACPI_EXTERN extern
#endif #endif
/*
* Keep local copies of these FADT-based registers. NOTE: These globals
* are first in this file for alignment reasons on 64-bit systems.
*/
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
/***************************************************************************** /*****************************************************************************
* *
...@@ -97,6 +103,11 @@ ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT; ...@@ -97,6 +103,11 @@ ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT;
ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT; ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT;
ACPI_EXTERN FACS_DESCRIPTOR *acpi_gbl_FACS; ACPI_EXTERN FACS_DESCRIPTOR *acpi_gbl_FACS;
ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS; ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS;
/*
* Since there may be multiple SSDTs and PSDTS, a single pointer is not
* sufficient; Therefore, there isn't one!
*/
/* /*
* Handle both ACPI 1.0 and ACPI 2.0 Integer widths * Handle both ACPI 1.0 and ACPI 2.0 Integer widths
...@@ -107,17 +118,6 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width; ...@@ -107,17 +118,6 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
ACPI_EXTERN u8 acpi_gbl_integer_byte_width; ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
/* Keep local copies of these FADT-based registers */
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
/*
* Since there may be multiple SSDTs and PSDTS, a single pointer is not
* sufficient; Therefore, there isn't one!
*/
/* /*
* ACPI Table info arrays * ACPI Table info arrays
*/ */
...@@ -165,7 +165,8 @@ ACPI_EXTERN u8 acpi_gbl_events_initialized; ...@@ -165,7 +165,8 @@ ACPI_EXTERN u8 acpi_gbl_events_initialized;
extern u8 acpi_gbl_shutdown; extern u8 acpi_gbl_shutdown;
extern u32 acpi_gbl_startup_flags; extern u32 acpi_gbl_startup_flags;
extern const u8 acpi_gbl_decode_to8bit[8]; extern const u8 acpi_gbl_decode_to8bit[8];
extern const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT]; extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT];
extern const char *acpi_gbl_highest_dstate_names[4];
extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES];
extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
......
...@@ -880,7 +880,8 @@ struct acpi_device_info ...@@ -880,7 +880,8 @@ struct acpi_device_info
{ {
ACPI_COMMON_OBJ_INFO; ACPI_COMMON_OBJ_INFO;
u32 valid; /* Indicates which fields are valid */ u8 highest_dstates[4]; /* _sx_d values 0xFF indicates not valid */
u32 valid; /* Indicates which fields below are valid */
u32 current_status; /* _STA value */ u32 current_status; /* _STA value */
acpi_integer address; /* _ADR value if any */ acpi_integer address; /* _ADR value if any */
struct acpi_device_id hardware_id; /* _HID value if any */ struct acpi_device_id hardware_id; /* _HID value if any */
......
...@@ -508,6 +508,10 @@ acpi_ut_execute_UID ( ...@@ -508,6 +508,10 @@ acpi_ut_execute_UID (
struct acpi_namespace_node *device_node, struct acpi_namespace_node *device_node,
struct acpi_device_id *uid); struct acpi_device_id *uid);
acpi_status
acpi_ut_execute_sxds (
struct acpi_namespace_node *device_node,
u8 *highest);
/* /*
* ut_mutex - mutual exclusion interfaces * ut_mutex - mutual exclusion interfaces
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment