From 9cbfa18e8a7b34a32eddbd914a07f085962f50a8 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 26 May 2010 11:22:41 +0800 Subject: ACPICA: Limit maximum time for Sleep() operator To prevent accidental deep sleeps, limit the maximum time that Sleep() will sleep. Configurable, default maximum is two seconds. ACPICA bugzilla 854. http://www.acpica.org/bugzilla/show_bug.cgi?id=854 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acconfig.h | 4 ++++ drivers/acpi/acpica/exsystem.c | 8 ++++++++ 2 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index 33181ad350d5..b17d8de9f6ff 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h @@ -119,6 +119,10 @@ #define ACPI_MAX_LOOP_ITERATIONS 0xFFFF +/* Maximum sleep allowed via Sleep() operator */ + +#define ACPI_MAX_SLEEP 20000 /* Two seconds */ + /****************************************************************************** * * ACPI Specification constants (Do not change unless the specification changes) diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index 6d32e09327f1..675aaa91a770 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -201,6 +201,14 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long) acpi_ex_relinquish_interpreter(); + /* + * For compatibility with other ACPI implementations and to prevent + * accidental deep sleeps, limit the sleep time to something reasonable. + */ + if (how_long > ACPI_MAX_SLEEP) { + how_long = ACPI_MAX_SLEEP; + } + acpi_os_sleep(how_long); /* And now we must get the interpreter again */ -- cgit v1.2.3 From b681f7d9ab4d697a214fa4428795790c3a937a89 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 26 May 2010 11:50:48 +0800 Subject: ACPICA: Truncate I/O addresses to 16 bits for Windows compatibility This feature is optional and is enabled if the BIOS requests any Windows OSI strings. It can also be enabled by the host OS. Signed-off-by: Matthew Garrett Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acglobal.h | 8 ++++++++ drivers/acpi/acpica/hwvalid.c | 12 ++++++++++++ drivers/acpi/acpica/nsinit.c | 9 +++++++++ include/acpi/acpixf.h | 1 + 4 files changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 9070f1fe8f17..899d68afc3c5 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -125,6 +125,14 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); */ u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE); +/* + * Optionally truncate I/O addresses to 16 bits. Provides compatibility + * with other ACPI implementations. NOTE: During ACPICA initialization, + * this value is set to TRUE if any Windows OSI strings have been + * requested by the BIOS. + */ +u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE); + /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ struct acpi_table_fadt acpi_gbl_FADT; diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index c10d587c1641..e1d9c777b213 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -222,6 +222,12 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) u32 one_byte; u32 i; + /* Truncate address to 16 bits if requested */ + + if (acpi_gbl_truncate_io_addresses) { + address &= ACPI_UINT16_MAX; + } + /* Validate the entire request and perform the I/O */ status = acpi_hw_validate_io_request(address, width); @@ -279,6 +285,12 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width) acpi_status status; u32 i; + /* Truncate address to 16 bits if requested */ + + if (acpi_gbl_truncate_io_addresses) { + address &= ACPI_UINT16_MAX; + } + /* Validate the entire request and perform the I/O */ status = acpi_hw_validate_io_request(address, width); diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 9bd6f050f299..4e5272c313e0 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -193,6 +193,15 @@ acpi_status acpi_ns_initialize_devices(void) acpi_ns_init_one_device, NULL, &info, NULL); + /* + * Any _OSI requests should be completed by now. If the BIOS has + * requested any Windows OSI strings, we will always truncate + * I/O addresses to 16 bits -- for Windows compatibility. + */ + if (acpi_gbl_osi_data >= ACPI_OSI_WIN_2000) { + acpi_gbl_truncate_io_addresses = TRUE; + } + ACPI_FREE(info.evaluate_info); if (ACPI_FAILURE(status)) { goto error_exit; diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 0e4ab1fe5966..1371cc997393 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -69,6 +69,7 @@ extern acpi_name acpi_gbl_trace_method_name; extern u32 acpi_gbl_trace_flags; extern u8 acpi_gbl_enable_aml_debug_object; extern u8 acpi_gbl_copy_dsdt_locally; +extern u8 acpi_gbl_truncate_io_addresses; extern u32 acpi_current_gpe_count; extern struct acpi_table_fadt acpi_gbl_FADT; -- cgit v1.2.3