patch-2.3.99-pre7 linux/arch/i386/kernel/acpi.c
Next file: linux/arch/i386/kernel/apic.c
Previous file: linux/arch/i386/defconfig
Back to the patch index
Back to the overall index
- Lines: 145
- Date:
Wed May 3 09:06:37 2000
- Orig file:
v2.3.99-pre6/linux/arch/i386/kernel/acpi.c
- Orig date:
Wed Apr 26 16:34:06 2000
diff -u --recursive --new-file v2.3.99-pre6/linux/arch/i386/kernel/acpi.c linux/arch/i386/kernel/acpi.c
@@ -144,14 +144,21 @@
struct acpi_errata_info
{
- const char *oem;
- const char *oem_table;
- u32 oem_rev;
- unsigned long options;
+ const char *signature; // table signature (eg. "RSDT")
+ const char *oem; // OEM name
+ const char *oem_table; // OEM table identifier (optional)
+ u32 oem_rev; // OEM table revision (optional)
+ unsigned long options; // errata options
};
+/*
+ * We must identify systems that need ACPI_TRUST_TABLES solely from the
+ * RSDP ("RSD PTR "). All other options should be flagged from the
+ * RSDT ("RSDT") which can be better identified.
+ */
struct acpi_errata_info acpi_errata[] =
{
+ {"RSD PTR ", "AMI ", NULL, 0, ACPI_TRUST_TABLES | ACPI_COPY_TABLES},
{NULL, NULL, 0, 0},
};
@@ -521,6 +528,51 @@
}
/*
+ * Match ACPI table and set options based on platform errata, if any
+ */
+static int __init acpi_find_errata(struct acpi_table *table)
+{
+ struct acpi_errata_info *info;
+ int size;
+
+ for (info = acpi_errata; info->signature && info->oem; info++) {
+ size = strlen(info->signature);
+ if (memcmp(&table->signature, info->signature, size))
+ continue;
+ if (strcmp(info->signature, "RSD PTR ")) {
+ // ordinary ACPI table
+ size = strlen(info->oem);
+ if (memcmp(table->oem, info->oem, size))
+ continue;
+ if (info->oem_table) {
+ size = strlen(info->oem_table);
+ if (memcmp(table->oem_table,
+ info->oem_table,
+ size))
+ continue;
+ }
+ if (info->oem_rev && table->oem_rev != info->oem_rev)
+ continue;
+ }
+ else {
+ // special handling for RSDP
+ size = strlen(info->oem);
+ if (memcmp(((struct acpi_rsdp*) table)->oem,
+ info->oem,
+ size))
+ continue;
+ }
+
+ printk(KERN_INFO
+ "ACPI: found platform errata 0x%08lx\n",
+ info->options);
+ acpi_opts |= info->options;
+ return 0;
+ }
+ return -1;
+}
+
+/*
* Locate and map ACPI tables
*/
static int __init acpi_find_tables(void)
@@ -556,6 +608,14 @@
if (i >= ACPI_BIOS_ROM_END)
return -ENODEV;
+ // find any errata based on the RSDP
+ if (!acpi_find_errata((struct acpi_table*) rsdp)) {
+ if (acpi_opts & ACPI_DISABLED)
+ return -EINVAL;
+ else if (acpi_opts & ACPI_CHIPSET_ONLY)
+ return -ENODEV;
+ }
+
// fetch RSDT from RSDP
rsdt = acpi_map_table(rsdp->rsdt);
if (!rsdt) {
@@ -569,6 +629,15 @@
acpi_unmap_table(rsdt);
return -EINVAL;
}
+
+ // find any errata based on the RSDT
+ if (!acpi_find_errata(rsdt)) {
+ if (acpi_opts & ACPI_DISABLED)
+ return -EINVAL;
+ else if (acpi_opts & ACPI_CHIPSET_ONLY)
+ return -ENODEV;
+ }
+
// search RSDT for FACP
acpi_facp.table = NULL;
rsdt_entry = (u32 *) (rsdt + 1);
@@ -631,11 +700,7 @@
if (!(pmregmisc & ACPI_PIIX4_PMIOSE))
return -ENODEV;
- pci_read_config_dword(dev, 0x40, &base);
- if (!(base & PCI_BASE_ADDRESS_SPACE_IO))
- return -ENODEV;
-
- base &= PCI_BASE_ADDRESS_IO_MASK;
+ base = dev->resource[PCI_BRIDGE_RESOURCES].start & PCI_BASE_ADDRESS_IO_MASK;
if (!base)
return -ENODEV;
@@ -688,16 +753,13 @@
if (!(tmp & 0x80))
return -ENODEV;
- pci_read_config_byte(dev, PCI_CLASS_REVISION, &tmp);
- tmp = (tmp & 0x10 ? 0x48 : 0x20);
-
- pci_read_config_dword(dev, tmp, &base);
- if (!(base & PCI_BASE_ADDRESS_SPACE_IO))
- return -ENODEV;
-
+ base = pci_resource_start(dev, PCI_BRIDGE_RESOURCES);
+ if (!base) {
+ base = pci_resource_start(dev, PCI_BASE_ADDRESS_4);
+ if (!base)
+ return -ENODEV;
+ }
base &= PCI_BASE_ADDRESS_IO_MASK;
- if (!base)
- return -ENODEV;
pci_read_config_byte(dev, 0x42, &irq);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)