diff options
author | Shaohua Li <shaohua.li@intel.com> | 2007-03-08 09:42:42 +0100 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-03-08 09:42:42 +0100 |
commit | 2f894ef9c8b36a35d80709bedca276d2fc691941 (patch) | |
tree | eb485e30373d1bf82a79952d89cd13579fee6045 | |
parent | Linux 2.6.21-rc3 (diff) | |
download | linux-2f894ef9c8b36a35d80709bedca276d2fc691941.tar.xz linux-2f894ef9c8b36a35d80709bedca276d2fc691941.zip |
ACPI: fix boot hang w/o "noapic" on MSI MS-6390-L
This is a workaround to handle a BIOS bug where the
programmer exchanged the name and index fields of
a _PRT entry. Apparently this BIOS error does not
confuse Windows and thus it lurks in the field
on various machines.
boot with "acpi=strict" to disable this workaround
http://bugzilla.kernel.org/show_bug.cgi?id=6859
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/acpi/resources/rscreate.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 1358c06a969c..cc48ab05676c 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -191,6 +191,9 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); for (index = 0; index < number_of_elements; index++) { + int source_name_index = 2; + int source_index_index = 3; + /* * Point user_prt past this current structure * @@ -261,10 +264,28 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, } /* + * If BIOS erroneously reversed the _PRT source_name and source_index, + * then reverse them back. + */ + if (ACPI_GET_OBJECT_TYPE (sub_object_list[3]) != ACPI_TYPE_INTEGER) { + if (acpi_gbl_enable_interpreter_slack) { + source_name_index = 3; + source_index_index = 2; + printk(KERN_WARNING "ACPI: Handling Garbled _PRT entry\n"); + } else { + ACPI_ERROR((AE_INFO, + "(PRT[%X].source_index) Need Integer, found %s", + index, + acpi_ut_get_object_type_name(sub_object_list[3]))); + return_ACPI_STATUS(AE_BAD_DATA); + } + } + + /* * 3) Third subobject: Dereference the PRT.source_name * The name may be unresolved (slack mode), so allow a null object */ - obj_desc = sub_object_list[2]; + obj_desc = sub_object_list[source_name_index]; if (obj_desc) { switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { case ACPI_TYPE_LOCAL_REFERENCE: @@ -339,7 +360,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /* 4) Fourth subobject: Dereference the PRT.source_index */ - obj_desc = sub_object_list[3]; + obj_desc = sub_object_list[source_index_index]; if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { user_prt->source_index = (u32) obj_desc->integer.value; } else { |