ACPICA: Truncate I/O addresses to 16 bits for Windows compatibility
Matthew Garrett [Wed, 26 May 2010 03:50:48 +0000 (11:50 +0800)]
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 <mjg@redhat.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>

drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/hwvalid.c
drivers/acpi/acpica/nsinit.c
include/acpi/acpixf.h

index 9070f1f..899d68a 100644 (file)
@@ -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;
index c10d587..e1d9c77 100644 (file)
@@ -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);
index 9bd6f05..4e5272c 100644 (file)
@@ -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;
index 0e4ab1f..1371cc9 100644 (file)
@@ -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;