# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1177 -> 1.1178 # include/acpi/acglobal.h 1.24 -> 1.25 # include/acpi/acutils.h 1.24 -> 1.25 # drivers/acpi/hardware/hwgpe.c 1.18 -> 1.19 # drivers/acpi/utilities/uteval.c 1.17 -> 1.18 # drivers/acpi/hardware/hwsleep.c 1.24 -> 1.25 # drivers/acpi/utilities/utglobal.c 1.25 -> 1.26 # drivers/acpi/resources/rsxface.c 1.16 -> 1.17 # include/acpi/acconfig.h 1.43 -> 1.44 # drivers/acpi/namespace/nsxfname.c 1.16 -> 1.17 # drivers/acpi/namespace/nseval.c 1.16 -> 1.17 # drivers/acpi/namespace/nsutils.c 1.24 -> 1.25 # include/acpi/actypes.h 1.29 -> 1.30 # drivers/acpi/hardware/hwregs.c 1.23 -> 1.24 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 04/02/27 len.brown@intel.com 1.1178 # [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. # -------------------------------------------- # diff -Nru a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c --- a/drivers/acpi/hardware/hwgpe.c Fri Feb 27 01:38:23 2004 +++ b/drivers/acpi/hardware/hwgpe.c Fri Feb 27 01:38:23 2004 @@ -528,6 +528,14 @@ /* Examine each GPE register within the block */ 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. * Blast them back in. diff -Nru a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c --- a/drivers/acpi/hardware/hwregs.c Fri Feb 27 01:38:23 2004 +++ b/drivers/acpi/hardware/hwregs.c Fri Feb 27 01:38:23 2004 @@ -152,11 +152,11 @@ /* * 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); if (ACPI_FAILURE (status)) { 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); } @@ -201,7 +201,7 @@ if (ACPI_FAILURE (status)) { 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); diff -Nru a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c --- a/drivers/acpi/hardware/hwsleep.c Fri Feb 27 01:38:23 2004 +++ b/drivers/acpi/hardware/hwsleep.c Fri Feb 27 01:38:23 2004 @@ -48,6 +48,19 @@ 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 @@ -171,19 +184,41 @@ /* 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) { 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) { 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. */ - 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) { ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); } @@ -477,19 +512,19 @@ /* Ignore any errors from these methods */ - arg.integer.value = 0; - status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL); + arg.integer.value = ACPI_SST_WAKING; + 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))); } 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) { 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) { ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status))); } @@ -501,8 +536,25 @@ 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 */ 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); } diff -Nru a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c --- a/drivers/acpi/namespace/nseval.c Fri Feb 27 01:38:23 2004 +++ b/drivers/acpi/namespace/nseval.c Fri Feb 27 01:38:23 2004 @@ -110,7 +110,7 @@ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto cleanup; } prefix_node = acpi_ns_map_handle_to_node (handle); @@ -197,7 +197,7 @@ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto cleanup; } /* Lookup the name in the namespace */ diff -Nru a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c --- a/drivers/acpi/namespace/nsutils.c Fri Feb 27 01:38:23 2004 +++ b/drivers/acpi/namespace/nsutils.c Fri Feb 27 01:38:23 2004 @@ -918,7 +918,7 @@ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto cleanup; } /* Setup lookup scope (search starting point) */ @@ -936,10 +936,10 @@ internal_path, acpi_format_exception (status))); } - /* Cleanup */ - (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); +cleanup: + /* Cleanup */ if (internal_path) { ACPI_MEM_FREE (internal_path); } diff -Nru a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c --- a/drivers/acpi/namespace/nsxfname.c Fri Feb 27 01:38:23 2004 +++ b/drivers/acpi/namespace/nsxfname.c Fri Feb 27 01:38:23 2004 @@ -326,6 +326,13 @@ 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; } diff -Nru a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c --- a/drivers/acpi/resources/rsxface.c Fri Feb 27 01:38:23 2004 +++ b/drivers/acpi/resources/rsxface.c Fri Feb 27 01:38:23 2004 @@ -239,6 +239,7 @@ acpi_status status; struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; struct acpi_resource *resource; + struct acpi_resource *buffer_end; ACPI_FUNCTION_TRACE ("acpi_walk_resources"); @@ -255,7 +256,13 @@ 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 (;;) { if (!resource || resource->id == ACPI_RSTYPE_END_TAG) { break; @@ -268,6 +275,7 @@ case AE_CTRL_DEPTH: /* Just keep going */ + status = AE_OK; break; @@ -285,7 +293,15 @@ goto cleanup; } + /* Get the next resource descriptor */ + resource = ACPI_NEXT_RESOURCE (resource); + + /* Check for end-of-buffer */ + + if (resource >= buffer_end) { + goto cleanup; + } } cleanup: diff -Nru a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c --- a/drivers/acpi/utilities/uteval.c Fri Feb 27 01:38:23 2004 +++ b/drivers/acpi/utilities/uteval.c Fri Feb 27 01:38:23 2004 @@ -562,3 +562,63 @@ acpi_ut_remove_reference (obj_desc); 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); +} diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c --- a/drivers/acpi/utilities/utglobal.c Fri Feb 27 01:38:23 2004 +++ b/drivers/acpi/utilities/utglobal.c Fri Feb 27 01:38:23 2004 @@ -171,7 +171,7 @@ 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_", "\\_S1_", "\\_S2_", @@ -179,6 +179,11 @@ "\\_S4_", "\\_S5_"}; +const char *acpi_gbl_highest_dstate_names[4] = { + "_S1D", + "_S2D", + "_S3D", + "_S4D"}; /****************************************************************************** * diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h --- a/include/acpi/acconfig.h Fri Feb 27 01:38:23 2004 +++ b/include/acpi/acconfig.h Fri Feb 27 01:38:23 2004 @@ -64,7 +64,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20040211 +#define ACPI_CA_VERSION 0x20040220 /* Maximum objects in the various object caches */ diff -Nru a/include/acpi/acglobal.h b/include/acpi/acglobal.h --- a/include/acpi/acglobal.h Fri Feb 27 01:38:23 2004 +++ b/include/acpi/acglobal.h Fri Feb 27 01:38:23 2004 @@ -57,6 +57,12 @@ #define ACPI_EXTERN extern #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 struct acpi_table_header *acpi_gbl_DSDT; ACPI_EXTERN FACS_DESCRIPTOR *acpi_gbl_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 @@ -107,17 +118,6 @@ ACPI_EXTERN u8 acpi_gbl_integer_byte_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 */ @@ -165,7 +165,8 @@ extern u8 acpi_gbl_shutdown; extern u32 acpi_gbl_startup_flags; 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 char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h --- a/include/acpi/actypes.h Fri Feb 27 01:38:23 2004 +++ b/include/acpi/actypes.h Fri Feb 27 01:38:23 2004 @@ -880,7 +880,8 @@ { 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 */ acpi_integer address; /* _ADR value if any */ struct acpi_device_id hardware_id; /* _HID value if any */ diff -Nru a/include/acpi/acutils.h b/include/acpi/acutils.h --- a/include/acpi/acutils.h Fri Feb 27 01:38:23 2004 +++ b/include/acpi/acutils.h Fri Feb 27 01:38:23 2004 @@ -508,6 +508,10 @@ struct acpi_namespace_node *device_node, struct acpi_device_id *uid); +acpi_status +acpi_ut_execute_sxds ( + struct acpi_namespace_node *device_node, + u8 *highest); /* * ut_mutex - mutual exclusion interfaces