summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2003-08-09 15:00:59 -0400
committerAndy Grover <agrover@groveronline.com>2003-08-09 15:00:59 -0400
commit68e4ad79294e8ff5361d4fc74472c121d2e2a9f2 (patch)
tree1ef761326ed5f4f119afad009051bdb9f9f6e2dc
parent0a5d9307f2f89ef3c87cc1955cf3f3366ff8b143 (diff)
ACPI from 2.4:
build: add ACPI_HT, delete ACPI_HT_ONLY boot: add acpi={force, off, ht}; delete "noht", "acpismp=" add DMI blacklist from UnitedLinux
-rw-r--r--Documentation/kbuild/kconfig-language.txt4
-rw-r--r--Documentation/kernel-parameters.txt13
-rw-r--r--arch/i386/Kconfig7
-rw-r--r--arch/i386/kernel/acpi/Makefile1
-rw-r--r--arch/i386/kernel/acpi/acpitable.c553
-rw-r--r--arch/i386/kernel/acpi/acpitable.h260
-rw-r--r--arch/i386/kernel/acpi/boot.c53
-rw-r--r--arch/i386/kernel/cpu/intel.c12
-rw-r--r--arch/i386/kernel/dmi_scan.c268
-rw-r--r--arch/i386/kernel/mpparse.c10
-rw-r--r--arch/i386/kernel/setup.c37
-rw-r--r--arch/i386/kernel/smpboot.c2
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/acpi/Kconfig106
-rw-r--r--drivers/acpi/Makefile5
-rw-r--r--drivers/acpi/bus.c2
-rw-r--r--drivers/acpi/tables.c21
-rw-r--r--include/asm-i386/acpi.h26
-rw-r--r--init/do_mounts.c10
19 files changed, 460 insertions, 932 deletions
diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt
index 40f85832e8b8..2a6cc95ddbda 100644
--- a/Documentation/kbuild/kconfig-language.txt
+++ b/Documentation/kbuild/kconfig-language.txt
@@ -124,8 +124,8 @@ module state. Dependency expressions have the following syntax:
<symbol> '!=' <symbol> (3)
'(' <expr> ')' (4)
'!' <expr> (5)
- <expr> '||' <expr> (6)
- <expr> '&&' <expr> (7)
+ <expr> '&&' <expr> (6)
+ <expr> '||' <expr> (7)
Expressions are listed in decreasing order of precedence.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 65032996a28c..6ea66bbf018f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -85,13 +85,10 @@ running once the system is up.
See also Documentation/scsi/ncr53c7xx.txt.
acpi= [HW,ACPI] Advanced Configuration and Power Interface
- Format: off
- off -- disables both ACPI table parsing and interpreter init
- See also Documentation/pm.txt.
-
- acpismp= [IA-32] Early setup parse and use ACPI SMP table.
- Format: force
- force -- force use of ACPI table parsing and interpreter init
+ Format: { force | off | ht }
+ force -- enables ACPI for systems with default off
+ off -- disabled ACPI for systems with default on
+ ht -- run only enough ACPI to enable Hyper Threading
See also Documentation/pm.txt.
ad1816= [HW,OSS]
@@ -619,8 +616,6 @@ running once the system is up.
instruction doesn't work correctly and not to
use it.
- noht [SMP,IA-32] Disables P4 Xeon(tm) HyperThreading.
-
noirqdebug [IA-32] Disables the code which attempts to detect and
disable unhandled interrupt sources.
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 95867bf35bea..8e1af735b40c 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -851,8 +851,11 @@ config SOFTWARE_SUSPEND
source "drivers/acpi/Kconfig"
+menu "APM (Advanced Power Management) BIOS Support"
+depends on PM
+
config APM
- tristate "Advanced Power Management BIOS support"
+ tristate "APM (Advanced Power Management) BIOS support"
depends on PM
---help---
APM is a BIOS specification for saving power using several different
@@ -996,6 +999,8 @@ config APM_REAL_MODE_POWER_OFF
a work-around for a number of buggy BIOSes. Switch this option on if
your computer crashes instead of powering off properly.
+endmenu
+
source "arch/i386/kernel/cpu/cpufreq/Kconfig"
endmenu
diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile
index 41f9b6fa4987..2cf76a941847 100644
--- a/arch/i386/kernel/acpi/Makefile
+++ b/arch/i386/kernel/acpi/Makefile
@@ -1,4 +1,3 @@
-obj-$(CONFIG_ACPI_HT_ONLY) := acpitable.o
obj-$(CONFIG_ACPI_BOOT) := boot.o
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o
diff --git a/arch/i386/kernel/acpi/acpitable.c b/arch/i386/kernel/acpi/acpitable.c
deleted file mode 100644
index ebcde5af1b72..000000000000
--- a/arch/i386/kernel/acpi/acpitable.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1)
- *
- * Copyright (C) 1999 Andrew Henroid
- * Copyright (C) 2001 Richard Schaal
- * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- * Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
- * Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * $Id: acpitable.c,v 1.7 2001/11/04 12:21:18 fenrus Exp $
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/stddef.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <asm/mpspec.h>
-#include <asm/io.h>
-#include <asm/apic.h>
-#include <asm/apicdef.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-#include "acpitable.h"
-
-static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT];
-
-int acpi_lapic;
-
-static unsigned char __init
-acpi_checksum(void *buffer, int length)
-{
- int i;
- unsigned char *bytebuffer;
- unsigned char sum = 0;
-
- if (!buffer || length <= 0)
- return 0;
-
- bytebuffer = (unsigned char *) buffer;
-
- for (i = 0; i < length; i++)
- sum += *(bytebuffer++);
-
- return sum;
-}
-
-static void __init
-acpi_print_table_header(acpi_table_header * header)
-{
- if (!header)
- return;
-
- printk(KERN_INFO "ACPI table found: %.4s v%d [%.6s %.8s %d.%d]\n",
- header->signature, header->revision, header->oem_id,
- header->oem_table_id, header->oem_revision >> 16,
- header->oem_revision & 0xffff);
-
- return;
-}
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_tb_scan_memory_for_rsdp
- *
- * PARAMETERS: address - Starting pointer for search
- * length - Maximum length to search
- *
- * RETURN: Pointer to the RSDP if found and valid, otherwise NULL.
- *
- * DESCRIPTION: Search a block of memory for the RSDP signature
- *
- ******************************************************************************/
-
-static void *__init
-acpi_tb_scan_memory_for_rsdp(void *address, int length)
-{
- u32 offset;
-
- if (length <= 0)
- return NULL;
-
- /* Search from given start addr for the requested length */
-
- offset = 0;
-
- while (offset < length) {
- /* The signature must match and the checksum must be correct */
- if (strncmp(address, RSDP_SIG, sizeof(RSDP_SIG) - 1) == 0 &&
- acpi_checksum(address, RSDP_CHECKSUM_LENGTH) == 0) {
- /* If so, we have found the RSDP */
- printk(KERN_INFO "ACPI: RSDP located at physical address %p\n",
- address);
- return address;
- }
- offset += RSDP_SCAN_STEP;
- address += RSDP_SCAN_STEP;
- }
-
- /* Searched entire block, no RSDP was found */
- printk(KERN_INFO "ACPI: Searched entire block, no RSDP was found.\n");
- return NULL;
-}
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_find_root_pointer
- *
- * PARAMETERS: none
- *
- * RETURN: physical address of the RSDP
- *
- * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
- * pointer structure. If it is found, set *RSDP to point to it.
- *
- * NOTE: The RSDP must be either in the first 1_k of the Extended
- * BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section
- * 5.2.2; assertion #421).
- *
- ******************************************************************************/
-
-static struct acpi_table_rsdp * __init
-acpi_find_root_pointer(void)
-{
- struct acpi_table_rsdp * rsdp;
-
- /*
- * Physical address is given
- */
- /*
- * Region 1) Search EBDA (low memory) paragraphs
- */
- rsdp = acpi_tb_scan_memory_for_rsdp(__va(LO_RSDP_WINDOW_BASE),
- LO_RSDP_WINDOW_SIZE);
-
- if (rsdp)
- return rsdp;
-
- /*
- * Region 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
- */
- rsdp = acpi_tb_scan_memory_for_rsdp(__va(HI_RSDP_WINDOW_BASE),
- HI_RSDP_WINDOW_SIZE);
-
-
-
- if (rsdp)
- return rsdp;
-
- printk(KERN_ERR "ACPI: System description tables not found\n");
- return NULL;
-}
-
-
-/*
- * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
- * to map the target physical address. The problem is that set_fixmap()
- * provides a single page, and it is possible that the page is not
- * sufficient.
- * By using this area, we can map up to MAX_IO_APICS pages temporarily,
- * i.e. until the next __va_range() call.
- *
- * Important Safety Note: The fixed I/O APIC page numbers are *subtracted*
- * from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and
- * count idx down while incrementing the phys address.
- */
-static __init char *
-__va_range(unsigned long phys, unsigned long size)
-{
- unsigned long base, offset, mapped_size;
- int idx;
-
- offset = phys & (PAGE_SIZE - 1);
- mapped_size = PAGE_SIZE - offset;
- set_fixmap(FIX_IO_APIC_BASE_END, phys);
- base = fix_to_virt(FIX_IO_APIC_BASE_END);
- dprintk("__va_range(0x%lx, 0x%lx): idx=%d mapped at %lx\n", phys, size,
- FIX_IO_APIC_BASE_END, base);
-
- /*
- * Most cases can be covered by the below.
- */
- idx = FIX_IO_APIC_BASE_END;
- while (mapped_size < size) {
- if (--idx < FIX_IO_APIC_BASE_0)
- return 0; /* cannot handle this */
- phys += PAGE_SIZE;
- set_fixmap(idx, phys);
- mapped_size += PAGE_SIZE;
- }
-
- return ((unsigned char *) base + offset);
-}
-
-static int __init acpi_tables_init(void)
-{
- int result = -ENODEV;
- acpi_table_header *header = NULL;
- struct acpi_table_rsdp *rsdp = NULL;
- struct acpi_table_rsdt *rsdt = NULL;
- struct acpi_table_rsdt saved_rsdt;
- int tables = 0;
- int type = 0;
- int i = 0;
-
-
- rsdp = (struct acpi_table_rsdp *) acpi_find_root_pointer();
-
- if (!rsdp)
- return -ENODEV;
-
- printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision,
- rsdp->oem_id);
-
- if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) {
- printk(KERN_WARNING "RSDP table signature incorrect\n");
- return -EINVAL;
- }
-
- rsdt = (struct acpi_table_rsdt *)
- __va_range(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt));
-
- if (!rsdt) {
- printk(KERN_WARNING "ACPI: Invalid root system description tables (RSDT)\n");
- return -ENODEV;
- }
-
- header = & rsdt->header;
- acpi_print_table_header(header);
-
- if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) {
- printk(KERN_WARNING "ACPI: RSDT signature incorrect\n");
- return -ENODEV;
- }
-
- /*
- * The number of tables is computed by taking the
- * size of all entries (header size minus total
- * size of RSDT) divided by the size of each entry
- * (4-byte table pointers).
- */
- tables = (header->length - sizeof(acpi_table_header)) / 4;
-
- memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
-
- if (saved_rsdt.header.length > sizeof(saved_rsdt)) {
- printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", saved_rsdt.header.length);
- return -ENODEV;
- }
-
- for (i = 0; i < tables; i++) {
- /* Map in header, then map in full table length. */
- header = (acpi_table_header *)
- __va_range(saved_rsdt.entry[i],
- sizeof(acpi_table_header));
- if (!header)
- break;
- header = (acpi_table_header *)
- __va_range(saved_rsdt.entry[i], header->length);
- if (!header)
- break;
-
- acpi_print_table_header(header);
-
- if (acpi_checksum(header,header->length)) {
- printk(KERN_WARNING "ACPI %s has invalid checksum\n",
- acpi_table_signatures[i]);
- continue;
- }
-
- for (type = 0; type < ACPI_TABLE_COUNT; type++)
- if (!strncmp((char *) &header->signature,
- acpi_table_signatures[type],strlen(acpi_table_signatures[type])))
- break;
-
- if (type >= ACPI_TABLE_COUNT) {
- printk(KERN_WARNING "ACPI: Unsupported table %.4s\n",
- header->signature);
- continue;
- }
-
-
- if (!acpi_boot_ops[type])
- continue;
-
- result = acpi_boot_ops[type] (header,
- (unsigned long) saved_rsdt.
- entry[i]);
- }
-
- return result;
-}
-
-static int total_cpus __initdata = 0;
-int have_acpi_tables;
-
-extern void __init MP_processor_info(struct mpc_config_processor *);
-
-static void __init
-acpi_parse_lapic(struct acpi_table_lapic *local_apic)
-{
- struct mpc_config_processor proc_entry;
- int ix = 0;
-
- if (!local_apic)
- return;
-
- printk(KERN_INFO "LAPIC (acpi_id[0x%04x] id[0x%x] enabled[%d])\n",
- local_apic->acpi_id, local_apic->id, local_apic->flags.enabled);
-
- printk(KERN_INFO "CPU %d (0x%02x00)", total_cpus, local_apic->id);
-
- if (local_apic->flags.enabled) {
- printk(" enabled");
- ix = local_apic->id;
- if (ix >= MAX_APICS) {
- printk(KERN_WARNING
- "Processor #%d INVALID - (Max ID: %d).\n", ix,
- MAX_APICS);
- return;
- }
- /*
- * Fill in the info we want to save. Not concerned about
- * the processor ID. Processor features aren't present in
- * the table.
- */
- proc_entry.mpc_type = MP_PROCESSOR;
- proc_entry.mpc_apicid = local_apic->id;
- proc_entry.mpc_cpuflag = CPU_ENABLED;
- if (proc_entry.mpc_apicid == boot_cpu_physical_apicid) {
- printk(" (BSP)");
- proc_entry.mpc_cpuflag |= CPU_BOOTPROCESSOR;
- }
- proc_entry.mpc_cpufeature =
- (boot_cpu_data.x86 << 8) |
- (boot_cpu_data.x86_model << 4) |
- boot_cpu_data.x86_mask;
- proc_entry.mpc_featureflag = boot_cpu_data.x86_capability[0];
- proc_entry.mpc_reserved[0] = 0;
- proc_entry.mpc_reserved[1] = 0;
- proc_entry.mpc_apicver = 0x10; /* integrated APIC */
- MP_processor_info(&proc_entry);
- } else {
- printk(" disabled");
- }
- printk("\n");
-
- total_cpus++;
- return;
-}
-
-static void __init
-acpi_parse_ioapic(struct acpi_table_ioapic *ioapic)
-{
-
- if (!ioapic)
- return;
-
- printk(KERN_INFO
- "IOAPIC (id[0x%x] address[0x%x] global_irq_base[0x%x])\n",
- ioapic->id, ioapic->address, ioapic->global_irq_base);
-
- if (nr_ioapics >= MAX_IO_APICS) {
- printk(KERN_WARNING
- "Max # of I/O APICs (%d) exceeded (found %d).\n",
- MAX_IO_APICS, nr_ioapics);
-/* panic("Recompile kernel with bigger MAX_IO_APICS!\n"); */
- }
-}
-
-
-/* Interrupt source overrides inform the machine about exceptions
- to the normal "PIC" mode interrupt routing */
-
-static void __init
-acpi_parse_int_src_ovr(struct acpi_table_int_src_ovr *intsrc)
-{
- if (!intsrc)
- return;
-
- printk(KERN_INFO
- "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n",
- intsrc->bus, intsrc->bus_irq, intsrc->global_irq,
- intsrc->flags.polarity, intsrc->flags.trigger);
-}
-
-/*
- * At this point, we look at the interrupt assignment entries in the MPS
- * table.
- */
-
-static void __init acpi_parse_nmi_src(struct acpi_table_nmi_src *nmisrc)
-{
- if (!nmisrc)
- return;
-
- printk(KERN_INFO
- "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n",
- nmisrc->flags.polarity, nmisrc->flags.trigger,
- nmisrc->global_irq);
-
-}
-static void __init
-acpi_parse_lapic_nmi(struct acpi_table_lapic_nmi *localnmi)
-{
- if (!localnmi)
- return;
-
- printk(KERN_INFO
- "LAPIC_NMI (acpi_id[0x%04x] polarity[0x%x] trigger[0x%x] lint[0x%x])\n",
- localnmi->acpi_id, localnmi->flags.polarity,
- localnmi->flags.trigger, localnmi->lint);
-}
-static void __init
-acpi_parse_lapic_addr_ovr(struct acpi_table_lapic_addr_ovr *lapic_addr_ovr)
-{
- if (!lapic_addr_ovr)
- return;
-
- printk(KERN_INFO "LAPIC_ADDR_OVR (address[0x%lx])\n",
- (unsigned long) lapic_addr_ovr->address);
-
-}
-
-static void __init
-acpi_parse_plat_int_src(struct acpi_table_plat_int_src *plintsrc)
-{
- if (!plintsrc)
- return;
-
- printk(KERN_INFO
- "PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
- plintsrc->flags.polarity, plintsrc->flags.trigger,
- plintsrc->type, plintsrc->id, plintsrc->eid,
- plintsrc->iosapic_vector, plintsrc->global_irq);
-}
-static int __init
-acpi_parse_madt(acpi_table_header * header, unsigned long phys)
-{
-
- struct acpi_table_madt *madt;
- acpi_madt_entry_header *entry_header;
- int table_size;
-
- madt = (struct acpi_table_madt *) __va_range(phys, header->length);
-
- if (!madt)
- return -EINVAL;
-
- table_size = (int) (header->length - sizeof(*madt));
- entry_header =
- (acpi_madt_entry_header *) ((void *) madt + sizeof(*madt));
-
- while (entry_header && (table_size > 0)) {
- switch (entry_header->type) {
- case ACPI_MADT_LAPIC:
- acpi_parse_lapic((struct acpi_table_lapic *)
- entry_header);
- break;
- case ACPI_MADT_IOAPIC:
- acpi_parse_ioapic((struct acpi_table_ioapic *)
- entry_header);
- break;
- case ACPI_MADT_INT_SRC_OVR:
- acpi_parse_int_src_ovr((struct acpi_table_int_src_ovr *)
- entry_header);
- break;
- case ACPI_MADT_NMI_SRC:
- acpi_parse_nmi_src((struct acpi_table_nmi_src *)
- entry_header);
- break;
- case ACPI_MADT_LAPIC_NMI:
- acpi_parse_lapic_nmi((struct acpi_table_lapic_nmi *)
- entry_header);
- break;
- case ACPI_MADT_LAPIC_ADDR_OVR:
- acpi_parse_lapic_addr_ovr((struct
- acpi_table_lapic_addr_ovr *)
- entry_header);
- break;
- case ACPI_MADT_PLAT_INT_SRC:
- acpi_parse_plat_int_src((struct acpi_table_plat_int_src
- *) entry_header);
- break;
- default:
- printk(KERN_WARNING
- "Unsupported MADT entry type 0x%x\n",
- entry_header->type);
- break;
- }
- table_size -= entry_header->length;
- entry_header =
- (acpi_madt_entry_header *) ((void *) entry_header +
- entry_header->length);
- }
-
- if (!total_cpus) {
- printk("ACPI: No Processors found in the APCI table.\n");
- return -EINVAL;
- }
-
- printk(KERN_INFO "%d CPUs total\n", total_cpus);
-
- if (madt->lapic_address)
- mp_lapic_addr = madt->lapic_address;
- else
- mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-
- printk(KERN_INFO "Local APIC address %x\n", madt->lapic_address);
-
- return 0;
-}
-
-
-/*
- * Configure the processor info using MADT in the ACPI tables. If we fail to
- * configure that, then we use the MPS tables.
- */
-void __init
-acpi_boot_init(void)
-{
-
- memset(&acpi_boot_ops, 0, sizeof(acpi_boot_ops));
- acpi_boot_ops[ACPI_APIC] = acpi_parse_madt;
-
- /*
- * Only do this when requested, either because of CPU/Bios type or from the command line
- */
-
- if (!acpi_tables_init())
- acpi_lapic = 1;
-}
-
diff --git a/arch/i386/kernel/acpi/acpitable.h b/arch/i386/kernel/acpi/acpitable.h
deleted file mode 100644
index ddf1c84a6549..000000000000
--- a/arch/i386/kernel/acpi/acpitable.h
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1)
- *
- * Copyright (C) 1999 Andrew Henroid
- * Copyright (C) 2001 Richard Schaal
- * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- * Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
- * Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * $Id: acpitable.h,v 1.3 2001/11/03 22:41:34 fenrus Exp $
- */
-
-/*
- * The following codes are cut&pasted from drivers/acpi. Part of the code
- * there can be not updated or delivered yet.
- * To avoid conflicts when CONFIG_ACPI is defined, the following codes are
- * modified so that they are self-contained in this file.
- * -- jun
- */
-
-#ifndef _HEADER_ACPITABLE_H_
-#define _HEADER_ACPITABLE_H_
-
-#define dprintk printk
-typedef unsigned int ACPI_TBLPTR;
-
-typedef struct { /* ACPI common table header */
- char signature[4]; /* identifies type of table */
- u32 length; /* length of table,
- in bytes, * including header */
- u8 revision; /* specification minor version # */
- u8 checksum; /* to make sum of entire table == 0 */
- char oem_id[6]; /* OEM identification */
- char oem_table_id[8]; /* OEM table identification */
- u32 oem_revision; /* OEM revision number */
- char asl_compiler_id[4]; /* ASL compiler vendor ID */
- u32 asl_compiler_revision; /* ASL compiler revision number */
-} acpi_table_header __attribute__ ((packed));;
-
-enum {
- ACPI_APIC = 0,
- ACPI_BOOT,
- ACPI_DBGP,
- ACPI_DSDT,
- ACPI_ECDT,
- ACPI_ETDT,
- ACPI_FACP,
- ACPI_FACS,
- ACPI_OEMX,
- ACPI_PSDT,
- ACPI_SBST,
- ACPI_SLIT,
- ACPI_SPCR,
- ACPI_SRAT,
- ACPI_SSDT,
- ACPI_SPMI,
- ACPI_XSDT,
- ACPI_TABLE_COUNT
-};
-
-static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
- "APIC",
- "BOOT",
- "DBGP",
- "DSDT",
- "ECDT",
- "ETDT",
- "FACP",
- "FACS",
- "OEM",
- "PSDT",
- "SBST",
- "SLIT",
- "SPCR",
- "SRAT",
- "SSDT",
- "SPMI",
- "XSDT"
-};
-
-struct acpi_table_madt {
- acpi_table_header header;
- u32 lapic_address;
- struct {
- u32 pcat_compat:1;
- u32 reserved:31;
- } flags __attribute__ ((packed));
-} __attribute__ ((packed));;
-
-enum {
- ACPI_MADT_LAPIC = 0,
- ACPI_MADT_IOAPIC,
- ACPI_MADT_INT_SRC_OVR,
- ACPI_MADT_NMI_SRC,
- ACPI_MADT_LAPIC_NMI,
- ACPI_MADT_LAPIC_ADDR_OVR,
- ACPI_MADT_IOSAPIC,
- ACPI_MADT_LSAPIC,
- ACPI_MADT_PLAT_INT_SRC,
- ACPI_MADT_ENTRY_COUNT
-};
-
-#define RSDP_SIG "RSD PTR "
-#define RSDT_SIG "RSDT"
-
-#define ACPI_DEBUG_PRINT(pl)
-
-#define ACPI_MEMORY_MODE 0x01
-#define ACPI_LOGICAL_ADDRESSING 0x00
-#define ACPI_PHYSICAL_ADDRESSING 0x01
-
-#define LO_RSDP_WINDOW_BASE 0 /* Physical Address */
-#define HI_RSDP_WINDOW_BASE 0xE0000 /* Physical Address */
-#define LO_RSDP_WINDOW_SIZE 0x400
-#define HI_RSDP_WINDOW_SIZE 0x20000
-#define RSDP_SCAN_STEP 16
-#define RSDP_CHECKSUM_LENGTH 20
-
-typedef int (*acpi_table_handler) (acpi_table_header * header, unsigned long);
-
-struct acpi_table_rsdp {
- char signature[8];
- u8 checksum;
- char oem_id[6];
- u8 revision;
- u32 rsdt_address;
-} __attribute__ ((packed));
-
-struct acpi_table_rsdt {
- acpi_table_header header;
- u32 entry[ACPI_TABLE_COUNT];
-} __attribute__ ((packed));
-
-typedef struct {
- u8 type;
- u8 length;
-} acpi_madt_entry_header __attribute__ ((packed));
-
-typedef struct {
- u16 polarity:2;
- u16 trigger:2;
- u16 reserved:12;
-} acpi_madt_int_flags __attribute__ ((packed));
-
-struct acpi_table_lapic {
- acpi_madt_entry_header header;
- u8 acpi_id;
- u8 id;
- struct {
- u32 enabled:1;
- u32 reserved:31;
- } flags __attribute__ ((packed));
-} __attribute__ ((packed));
-
-struct acpi_table_ioapic {
- acpi_madt_entry_header header;
- u8 id;
- u8 reserved;
- u32 address;
- u32 global_irq_base;
-} __attribute__ ((packed));
-
-struct acpi_table_int_src_ovr {
- acpi_madt_entry_header header;
- u8 bus;
- u8 bus_irq;
- u32 global_irq;
- acpi_madt_int_flags flags;
-} __attribute__ ((packed));
-
-struct acpi_table_nmi_src {
- acpi_madt_entry_header header;
- acpi_madt_int_flags flags;
- u32 global_irq;
-} __attribute__ ((packed));
-
-struct acpi_table_lapic_nmi {
- acpi_madt_entry_header header;
- u8 acpi_id;
- acpi_madt_int_flags flags;
- u8 lint;
-} __attribute__ ((packed));
-
-struct acpi_table_lapic_addr_ovr {
- acpi_madt_entry_header header;
- u8 reserved[2];
- u64 address;
-} __attribute__ ((packed));
-
-struct acpi_table_iosapic {
- acpi_madt_entry_header header;
- u8 id;
- u8 reserved;
- u32 global_irq_base;
- u64 address;
-} __attribute__ ((packed));
-
-struct acpi_table_lsapic {
- acpi_madt_entry_header header;
- u8 acpi_id;
- u8 id;
- u8 eid;
- u8 reserved[3];
- struct {
- u32 enabled:1;
- u32 reserved:31;
- } flags;
-} __attribute__ ((packed));
-
-struct acpi_table_plat_int_src {
- acpi_madt_entry_header header;
- acpi_madt_int_flags flags;
- u8 type;
- u8 id;
- u8 eid;
- u8 iosapic_vector;
- u32 global_irq;
- u32 reserved;
-} __attribute__ ((packed));
-
-/*
- * ACPI Table Descriptor. One per ACPI table
- */
-typedef struct acpi_table_desc {
- struct acpi_table_desc *prev;
- struct acpi_table_desc *next;
- struct acpi_table_desc *installed_desc;
- acpi_table_header *pointer;
- void *base_pointer;
- u8 *aml_pointer;
- u64 physical_address;
- u32 aml_length;
- u32 length;
- u32 count;
- u16 table_id;
- u8 type;
- u8 allocation;
- u8 loaded_into_namespace;
-
-} acpi_table_desc __attribute__ ((packed));;
-
-#endif
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 899c1784c14b..d0869a595a61 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -39,6 +39,7 @@
#define PREFIX "ACPI: "
extern int acpi_disabled;
+extern int acpi_ht;
/* --------------------------------------------------------------------------
Boot-time Configuration
@@ -157,7 +158,7 @@ acpi_parse_lapic_addr_ovr (
return 0;
}
-#ifndef CONFIG_ACPI_HT_ONLY
+#ifdef CONFIG_ACPI
static int __init
acpi_parse_lapic_nmi (
@@ -177,7 +178,7 @@ acpi_parse_lapic_nmi (
return 0;
}
-#endif /*CONFIG_ACPI_HT_ONLY*/
+#endif /*CONFIG_ACPI*/
#endif /*CONFIG_X86_LOCAL_APIC*/
@@ -185,7 +186,7 @@ acpi_parse_lapic_nmi (
int acpi_ioapic;
-#ifndef CONFIG_ACPI_HT_ONLY
+#ifdef CONFIG_ACPI
static int __init
acpi_parse_ioapic (
@@ -247,7 +248,7 @@ acpi_parse_nmi_src (
return 0;
}
-#endif /*!CONFIG_ACPI_HT_ONLY*/
+#endif /*CONFIG_ACPI*/
#endif /*CONFIG_X86_IO_APIC*/
@@ -289,12 +290,34 @@ acpi_find_rsdp (void)
return rsdp_phys;
}
+/*
+ * acpi_boot_init()
+ * called from setup_arch(), always.
+ * 1. maps ACPI tables for later use
+ * 2. enumerates lapics
+ * 3. enumerates io-apics
+ *
+ * side effects:
+ * acpi_lapic = 1 if LAPIC found
+ * acpi_ioapic = 1 if IOAPIC found
+ * if (acpi_lapic && acpi_ioapic) smp_found_config = 1;
+ * if acpi_blacklisted() acpi_disabled = 1;
+ * acpi_irq_model=...
+ * ...
+ *
+ * return value: (currently ignored)
+ * 0: success
+ * !0: failure
+ */
int __init
acpi_boot_init (void)
{
int result = 0;
+ if (acpi_disabled && !acpi_ht)
+ return 1;
+
/*
* The default interrupt routing model is PIC (8259). This gets
* overriden if IOAPICs are enumerated (below).
@@ -308,14 +331,14 @@ acpi_boot_init (void)
if (result)
return result;
+#ifdef CONFIG_ACPI
result = acpi_blacklisted();
if (result) {
printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n");
acpi_disabled = 1;
return result;
}
- else
- printk(KERN_NOTICE PREFIX "BIOS not listed in blacklist\n");
+#endif
#ifdef CONFIG_X86_LOCAL_APIC
@@ -366,27 +389,37 @@ acpi_boot_init (void)
return result;
}
-#ifndef CONFIG_ACPI_HT_ONLY
+#ifdef CONFIG_ACPI
result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi);
if (result < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
/* TBD: Cleanup to allow fallback to MPS */
return result;
}
-#endif /*!CONFIG_ACPI_HT_ONLY*/
+#endif /*CONFIG_ACPI*/
acpi_lapic = 1;
#endif /*CONFIG_X86_LOCAL_APIC*/
#ifdef CONFIG_X86_IO_APIC
-#ifndef CONFIG_ACPI_HT_ONLY
+#ifdef CONFIG_ACPI
/*
* I/O APIC
* --------
*/
+ /*
+ * ACPI interpreter is required to complete interrupt setup,
+ * so if it is off, don't enumerate the io-apics with ACPI.
+ * If MPS is present, it will handle them,
+ * otherwise the system will stay in PIC mode
+ */
+ if (acpi_disabled) {
+ return 1;
+ }
+
result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
if (!result) {
printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
@@ -418,7 +451,7 @@ acpi_boot_init (void)
acpi_ioapic = 1;
-#endif /*!CONFIG_ACPI_HT_ONLY*/
+#endif /*CONFIG_ACPI*/
#endif /*CONFIG_X86_IO_APIC*/
#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
index 1736d1a2115b..0a2ca6584a2d 100644
--- a/arch/i386/kernel/cpu/intel.c
+++ b/arch/i386/kernel/cpu/intel.c
@@ -11,7 +11,6 @@
#include "cpu.h"
-static int disable_P4_HT __initdata = 0;
extern int trap_init_f00f_bug(void);
#ifdef CONFIG_X86_INTEL_USERCOPY
@@ -68,13 +67,6 @@ int __init ppro_with_ram_bug(void)
return 0;
}
-static int __init P4_disable_ht(char *s)
-{
- disable_P4_HT = 1;
- return 1;
-}
-__setup("noht", P4_disable_ht);
-
#define LVL_1_INST 1
#define LVL_1_DATA 2
#define LVL_2 3
@@ -281,7 +273,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
strcpy(c->x86_model_id, p);
#ifdef CONFIG_X86_HT
- if (cpu_has(c, X86_FEATURE_HT) && !disable_P4_HT) {
+ if (cpu_has(c, X86_FEATURE_HT)) {
extern int phys_proc_id[NR_CPUS];
u32 eax, ebx, ecx, edx;
@@ -329,8 +321,6 @@ static void __init init_intel(struct cpuinfo_x86 *c)
}
too_many_siblings:
- if (disable_P4_HT)
- clear_bit(X86_FEATURE_HT, c->x86_capability);
#endif
/* Work around errata */
diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
index fb3e7b80621d..37bada136270 100644
--- a/arch/i386/kernel/dmi_scan.c
+++ b/arch/i386/kernel/dmi_scan.c
@@ -129,10 +129,10 @@ static int __init dmi_iterate(void (*decode)(struct dmi_header *))
* the SMBIOS version, which we don't know at this point.
*/
if(buf[14]!=0)
- dmi_printk((KERN_INFO "DMI %d.%d present.\n",
- buf[14]>>4, buf[14]&0x0F));
+ printk(KERN_INFO "DMI %d.%d present.\n",
+ buf[14]>>4, buf[14]&0x0F);
else
- dmi_printk((KERN_INFO "DMI present.\n"));
+ printk(KERN_INFO "DMI present.\n");
dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
num, len));
dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
@@ -162,6 +162,20 @@ enum
static char *dmi_ident[DMI_STRING_MAX];
+/* print some information suitable for a blacklist entry. */
+void dmi_dump_system(void)
+{
+ printk("DMI: BIOS: %.40s, %.40s, %.40s\n",
+ dmi_ident[DMI_BIOS_VENDOR], dmi_ident[DMI_BIOS_VERSION],
+ dmi_ident[DMI_BIOS_DATE]);
+ printk("DMI: System: %.40s, %.40s, %.40s\n",
+ dmi_ident[DMI_SYS_VENDOR], dmi_ident[DMI_PRODUCT_NAME],
+ dmi_ident[DMI_PRODUCT_VERSION]);
+ printk("DMI: Board: %.40s, %.40s, %.40s\n",
+ dmi_ident[DMI_BOARD_VENDOR], dmi_ident[DMI_BOARD_NAME],
+ dmi_ident[DMI_BOARD_VERSION]);
+}
+
/*
* Save a DMI string
*/
@@ -341,6 +355,31 @@ static __init int fix_broken_hp_bios_irq9(struct dmi_blacklist *d)
return 0;
}
+/* Some BIOS / motherboard combinations require the APIC to be enabled
+ * even on UP systems or will exhibit instability. */
+
+static int __init abit_apic_required(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+#ifndef CONFIG_SMP
+ extern int enable_apic_up;
+ extern int dont_enable_local_apic;
+ extern int skip_ioapic_setup;
+
+ if (!enable_apic_up) {
+ printk(KERN_WARNING " *** %s: APIC forcibly enabled to avoid "
+ "RANDOM CRASHES.\n", d->ident);
+ printk(KERN_WARNING " *** PLEASE add 'apic' to the kernel "
+ "commandline AND enable it in the BIOS! ***\n");
+ dont_enable_local_apic=0;
+ enable_apic_up=1;
+ skip_ioapic_setup=0;
+ }
+#endif
+#endif
+ return 0;
+}
+
/*
* Check for clue free BIOS implementations who use
* the following QA technique
@@ -416,6 +455,17 @@ static __init int broken_pirq(struct dmi_blacklist *d)
}
/*
+ * ASUS K7V-RM has broken ACPI table defining sleep modes
+ */
+
+static __init int broken_acpi_Sx(struct dmi_blacklist *d)
+{
+ printk(KERN_WARNING "Detected ASUS mainboard with broken ACPI sleep table\n");
+ dmi_broken |= BROKEN_ACPI_Sx;
+ return 0;
+}
+
+/*
* Toshiba keyboard likes to repeat keys when they are not repeated.
*/
@@ -496,6 +546,63 @@ static __init int print_if_true(struct dmi_blacklist *d)
return 0;
}
+
+extern int acpi_disabled, acpi_force;
+extern int enable_apic_up, skip_ioapic_setup;
+
+static __init __attribute__((unused)) int acpi_disable(struct dmi_blacklist *d)
+{
+ if (!acpi_force) {
+ printk(KERN_NOTICE "%s detected: acpi off\n",d->ident);
+ acpi_disabled = 1;
+ } else {
+ printk(KERN_NOTICE
+ "Warning: DMI blacklist says broken, but acpi forced\n");
+ }
+ return 0;
+}
+
+
+#ifdef CONFIG_ACPI_BOOT
+extern int acpi_ht;
+
+/*
+ * Limit ACPI to CPU enumeration for HT
+ */
+static __init __attribute__((unused)) int force_acpi_ht(struct dmi_blacklist *d)
+{
+ if (!acpi_force) {
+ printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident);
+ acpi_disabled = 1;
+ acpi_ht = 1;
+ } else {
+ printk(KERN_NOTICE
+ "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
+ }
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_ACPI_PCI
+static __init int disable_acpi_pci(struct dmi_blacklist *d)
+{
+ extern __init void pci_disable_acpi(void) ;
+
+ printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident);
+ pci_disable_acpi();
+ return 0;
+}
+#endif
+
+#ifndef CONFIG_SMP
+static __init int force_apic(struct dmi_blacklist *d)
+{
+ printk(KERN_NOTICE "%s detected: force APIC\n", d->ident);
+ enable_apic_up = 1;
+ skip_ioapic_setup = 0;
+ return 0;
+}
+#endif
/*
* Process the DMI blacklists
*/
@@ -558,6 +665,11 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"),
NO_MATCH, NO_MATCH
} },
+ { apm_is_horked, "ABIT KX7-333[R]", { /* APM blows on shutdown */
+ MATCH(DMI_BOARD_VENDOR, "ABIT"),
+ MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"),
+ NO_MATCH, NO_MATCH,
+ } },
{ apm_is_horked, "Trigem Delhi3", { /* APM crashes */
MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
MATCH(DMI_PRODUCT_NAME, "Delhi3"),
@@ -706,6 +818,12 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
NO_MATCH, NO_MATCH
} },
+ { abit_apic_required, "ABIT KX7-333[R]", { /* Will crash randomly w/o */
+ MATCH(DMI_BOARD_VENDOR, "ABIT"),
+ MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"),
+ NO_MATCH, NO_MATCH,
+ } },
+
/* Problem Intel 440GX bioses */
{ broken_pirq, "SABR1 Bios", { /* Bad $PIR */
@@ -741,6 +859,12 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
NO_MATCH, NO_MATCH, NO_MATCH
} },
+ { broken_acpi_Sx, "ASUS K7V-RM", { /* Bad ACPI Sx table */
+ MATCH(DMI_BIOS_VERSION,"ASUS K7V-RM ACPI BIOS Revision 1003A"),
+ MATCH(DMI_BOARD_NAME, "<K7V-RM>"),
+ NO_MATCH, NO_MATCH
+ } },
+
{ broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */
MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
NO_MATCH, NO_MATCH, NO_MATCH
@@ -799,6 +923,122 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
NO_MATCH, NO_MATCH,
} },
+ /*
+ * Boxes that need ACPI disabled
+ */
+
+ { acpi_disable, "IBM Thinkpad", {
+ MATCH(DMI_BOARD_VENDOR, "IBM"),
+ MATCH(DMI_BOARD_NAME, "2629H1G"),
+ NO_MATCH, NO_MATCH }},
+
+#ifdef CONFIG_ACPI_BOOT
+ /*
+ * Boxes that need acpi=ht
+ */
+
+ { force_acpi_ht, "FSC Primergy T850", {
+ MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "DELL GX240", {
+ MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
+ MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "HP VISUALIZE NT Workstation", {
+ MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+ MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "Compaq ProLiant DL380 G2", {
+ MATCH(DMI_SYS_VENDOR, "Compaq"),
+ MATCH(DMI_PRODUCT_NAME, "ProLiant DL380 G2"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "Compaq ProLiant ML530 G2", {
+ MATCH(DMI_SYS_VENDOR, "Compaq"),
+ MATCH(DMI_PRODUCT_NAME, "ProLiant ML530 G2"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "Compaq ProLiant ML350 G3", {
+ MATCH(DMI_SYS_VENDOR, "Compaq"),
+ MATCH(DMI_PRODUCT_NAME, "ProLiant ML350 G3"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "Compaq Workstation W8000", {
+ MATCH(DMI_SYS_VENDOR, "Compaq"),
+ MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "ASUS P4B266", {
+ MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ MATCH(DMI_BOARD_NAME, "P4B266"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "ASUS P2B-DS", {
+ MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ MATCH(DMI_BOARD_NAME, "P2B-DS"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "ASUS CUR-DLS", {
+ MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ MATCH(DMI_BOARD_NAME, "CUR-DLS"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "ASUS A7V", {
+ MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
+ MATCH(DMI_BOARD_NAME, "<A7V>"),
+ MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1011"), NO_MATCH }},
+
+ { force_acpi_ht, "ABIT i440BX-W83977", {
+ MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
+ MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "IBM Bladecenter", {
+ MATCH(DMI_BOARD_VENDOR, "IBM"),
+ MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "IBM eServer xSeries 360", {
+ MATCH(DMI_BOARD_VENDOR, "IBM"),
+ MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "IBM eserver xSeries 330", {
+ MATCH(DMI_BOARD_VENDOR, "IBM"),
+ MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
+ NO_MATCH, NO_MATCH }},
+
+ { force_acpi_ht, "IBM eserver xSeries 440", {
+ MATCH(DMI_BOARD_VENDOR, "IBM"),
+ MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
+ NO_MATCH, NO_MATCH }},
+#endif // CONFIG_ACPI_BOOT
+
+#ifdef CONFIG_ACPI_PCI
+ /*
+ * Boxes that need ACPI PCI IRQ routing disabled
+ */
+
+ { disable_acpi_pci, "ASUS A7V", {
+ MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
+ MATCH(DMI_BOARD_NAME, "<A7V>"),
+ MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"), NO_MATCH }},
+#endif
+
+#ifndef CONFIG_SMP
+ /*
+ * Enable APIC on UP kernels.
+ */
+
+ { force_apic, "Supermicro P4DC6", {
+ MATCH(DMI_BOARD_VENDOR, "Supermicro"),
+ MATCH(DMI_BOARD_NAME, "P4DC6"),
+ NO_MATCH, NO_MATCH } },
+#endif
{ NULL, }
};
@@ -808,11 +1048,31 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
* returns 1 or we hit the end.
*/
+#define ACPI_BLACKLIST_CUTOFF_YEAR 2001
+
static __init void dmi_check_blacklist(void)
{
struct dmi_blacklist *d;
int i;
+ if (dmi_ident[DMI_BIOS_DATE]) {
+ char *s = strrchr(dmi_ident[DMI_BIOS_DATE], '/');
+ if (s) {
+ int year, disable = 0;
+ s++;
+ year = simple_strtoul(s,NULL,0);
+ if (year >= 1000)
+ disable = year < ACPI_BLACKLIST_CUTOFF_YEAR;
+ else if (year < 1 || (year > 90 && year <= 99))
+ disable = 1;
+ if (disable && !acpi_force) {
+ printk(KERN_NOTICE "ACPI disabled because your bios is from %s and too old\n", s);
+ printk(KERN_NOTICE "You can enable it with acpi=force\n");
+ acpi_disabled = 1;
+ }
+ }
+ }
+
d=&dmi_blacklist[0];
while(d->callback)
{
@@ -892,6 +1152,8 @@ void __init dmi_scan_machine(void)
int err = dmi_iterate(dmi_decode);
if(err == 0)
dmi_check_blacklist();
+ else
+ printk(KERN_INFO "DMI not present.\n");
}
EXPORT_SYMBOL(is_unsafe_smbus);
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 131cf540b4b8..79666579a424 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -620,7 +620,7 @@ void __init get_smp_config (void)
/*
* ACPI may be used to obtain the entire SMP configuration or just to
- * enumerate/configure processors (CONFIG_ACPI_HT_ONLY). Note that
+ * enumerate/configure processors (CONFIG_ACPI_HT). Note that
* ACPI supports both logical (e.g. Hyper-Threading) and physical
* processors, where MPS only supports physical.
*/
@@ -1011,8 +1011,9 @@ void __init mp_config_acpi_legacy_irqs (void)
panic("Max # of irq sources exceeded!\n");
}
}
+#endif /* CONFIG_X86_IO_APIC */
-#ifndef CONFIG_ACPI_HT_ONLY
+#ifdef CONFIG_ACPI
/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
@@ -1067,8 +1068,7 @@ void __init mp_config_ioapic_for_sci(int irq)
io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 1, 1); // Active low, level triggered
}
-
-#endif /*CONFIG_ACPI_HT_ONLY*/
+#endif /* CONFIG_ACPI */
#ifdef CONFIG_ACPI_PCI
@@ -1149,6 +1149,4 @@ void __init mp_parse_prt (void)
#endif /*CONFIG_ACPI_PCI*/
-#endif /*CONFIG_X86_IO_APIC*/
-
#endif /*CONFIG_ACPI_BOOT*/
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 01a3990182c5..436d1366b255 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -62,13 +62,20 @@ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
unsigned long mmu_cr4_features;
EXPORT_SYMBOL_GPL(mmu_cr4_features);
-#ifdef CONFIG_ACPI_HT_ONLY
-int acpi_disabled = 1;
+#ifdef CONFIG_ACPI
+ int acpi_disabled __initdata = 0;
#else
-int acpi_disabled = 0;
+ int acpi_disabled __initdata = 1;
#endif
EXPORT_SYMBOL(acpi_disabled);
+#ifdef CONFIG_ACPI_BOOT
+ int acpi_ht __initdata = 1; /* enable HT */
+#endif
+
+int acpi_force __initdata = 0;
+
+
int MCA_bus;
/* for MCA, but anyone else can use it if they want */
unsigned int machine_id;
@@ -516,13 +523,26 @@ static void __init parse_cmdline_early (char ** cmdline_p)
}
}
- /* "acpi=off" disables both ACPI table parsing and interpreter init */
- if (c == ' ' && !memcmp(from, "acpi=off", 8))
+#ifdef CONFIG_ACPI_BOOT
+ /* "acpi=off" disables both ACPI table parsing and interpreter */
+ else if (!memcmp(from, "acpi=off", 8)) {
+ acpi_ht = 0;
acpi_disabled = 1;
+ }
- /* "acpismp=force" turns on ACPI again */
- if (c == ' ' && !memcmp(from, "acpismp=force", 13))
+ /* acpi=force to over-ride black-list */
+ else if (!memcmp(from, "acpi=force", 10)) {
+ acpi_force = 1;
+ acpi_ht=1;
acpi_disabled = 0;
+ }
+
+ /* Limit ACPI just to boot-time to enable HT */
+ else if (!memcmp(from, "acpi=ht", 7)) {
+ acpi_ht = 1;
+ if (!acpi_force) acpi_disabled = 1;
+ }
+#endif
/*
* highmem=size forces highmem to be exactly 'size' bytes.
@@ -982,8 +1002,7 @@ void __init setup_arch(char **cmdline_p)
/*
* Parse the ACPI tables for possible boot-time SMP configuration.
*/
- if (!acpi_disabled)
- acpi_boot_init();
+ (void) acpi_boot_init();
#endif
#ifdef CONFIG_X86_LOCAL_APIC
if (smp_found_config)
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 00c783cbd750..566ab287c7f8 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -954,7 +954,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
* If we couldn't find an SMP configuration at boot time,
* get out of here now!
*/
- if (!smp_found_config) {
+ if (!smp_found_config && !acpi_lapic) {
printk(KERN_NOTICE "SMP motherboard not detected.\n");
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = 1;
diff --git a/drivers/Makefile b/drivers/Makefile
index 737fa9fc26f6..ba1821c3c12a 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -7,7 +7,7 @@
obj-$(CONFIG_PCI) += pci/
obj-$(CONFIG_PARISC) += parisc/
-obj-$(CONFIG_ACPI) += acpi/
+obj-$(CONFIG_ACPI_BOOT) += acpi/
# PnP must come after ACPI since it will eventually need to check if acpi
# was used and do nothing if so
obj-$(CONFIG_PNP) += pnp/
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 769dd4e80cf8..e09a935b4a97 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -2,12 +2,36 @@
# ACPI Configuration
#
-menu "ACPI Support"
+menu "ACPI (Advanced Configuration and Power Interface) Support"
+
+config ACPI_HT
+ bool "ACPI Processor Enumeration for HT"
+ depends on (X86 && X86_LOCAL_APIC)
+ default y
+ ---help---
+ ACPI enumerates both logical (a.k.a. Hyper-Threaded -- HT)
+ and physical processors. It is designed to obsolete several older
+ specifications, including the MultiProcessor Specification (MPS),
+ which supported only physical processors.
+
+ CONFIG_ACPI_HT includes the minimal ACPI boot-time code
+ necessary to enumerate logical processors and enable HT.
+
+ CONFIG_ACPI includes CONFIG_ACPI_HT, plus IO APIC enumeration,
+ and the hooks to run the ACPI AML interpreter for run-time events.
+
+ When CONFIG_ACPI is selected, the command-line option "acpi=ht"
+ is available to run just the ACPI boot-time code -- just as if
+ only CONFIG_ACPI_HT were selected.
+
+ Note that "acpi=off" can be used to disable all ACPI code in the kernel.
config ACPI
- bool "ACPI Support" if X86
+ bool "Full ACPI Support"
depends on !X86_VISWS
- default y if IA64 && (!IA64_HP_SIM || IA64_SGI_SN)
+ depends on !IA64_HP_SIM
+ depends on IA64 || (X86 && ACPI_HT)
+ default y
---help---
Advanced Configuration and Power Interface (ACPI) support for
Linux requires an ACPI compliant platform (hardware/firmware),
@@ -36,30 +60,16 @@ config ACPI
available at:
<http://www.acpi.info>
-config ACPI_HT_ONLY
- bool "CPU Enumeration Only"
- depends on X86 && ACPI && X86_LOCAL_APIC
- ---help---
- This option enables limited ACPI support -- just enough to
- enumerate processors from the ACPI Multiple APIC Description
- Table (MADT). Note that ACPI supports both logical (e.g. Hyper-
- Threading) and physical processors, where the MultiProcessor
- Specification (MPS) table only supports physical processors.
-
- Full ACPI support (CONFIG_ACPI) is preferred. Use this option
- only if you wish to limit ACPI's role to processor enumeration.
-
- In this configuration, ACPI defaults to off. It must be enabled
- on the command-line with the "acpismp=force" option.
-
config ACPI_BOOT
bool
- depends on IA64 && (!IA64_HP_SIM || IA64_SGI_SN) || X86 && ACPI && !ACPI_HT_ONLY
+ depends on ACPI || ACPI_HT
default y
config ACPI_SLEEP
bool "Sleep States"
- depends on X86 && ACPI && !ACPI_HT_ONLY && SOFTWARE_SUSPEND
+ depends on X86 && ACPI
+ depends on SOFTWARE_SUSPEND
+ default y
---help---
This option adds support for ACPI suspend states.
@@ -83,7 +93,8 @@ config ACPI_SLEEP_PROC_FS
config ACPI_AC
tristate "AC Adapter"
- depends on X86 && ACPI && !ACPI_HT_ONLY
+ depends on X86 && ACPI
+ default m
help
This driver adds support for the AC Adapter object, which indicates
whether a system is on AC, or not. Typically, only mobile systems
@@ -91,7 +102,8 @@ config ACPI_AC
config ACPI_BATTERY
tristate "Battery"
- depends on X86 && ACPI && !ACPI_HT_ONLY
+ depends on X86 && ACPI
+ default m
help
This driver adds support for battery information through
/proc/acpi/battery. If you have a mobile system with a battery,
@@ -99,7 +111,9 @@ config ACPI_BATTERY
config ACPI_BUTTON
tristate "Button"
- depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
+ depends on ACPI
+ depends on !IA64_SGI_SN
+ default m
help
This driver registers for events based on buttons, such as the
power, sleep, and lid switch. In the future, a daemon will read
@@ -109,14 +123,18 @@ config ACPI_BUTTON
config ACPI_FAN
tristate "Fan"
- depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
+ depends on ACPI
+ depends on !IA64_SGI_SN
+ default m
help
This driver adds support for ACPI fan devices, allowing user-mode
applications to perform basic fan control (on, off, status).
config ACPI_PROCESSOR
tristate "Processor"
- depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
+ depends on ACPI
+ depends on !IA64_SGI_SN
+ default m
help
This driver installs ACPI as the idle handler for Linux, and uses
ACPI C2 and C3 processor states to save power, on systems that
@@ -125,6 +143,7 @@ config ACPI_PROCESSOR
config ACPI_THERMAL
tristate "Thermal Zone"
depends on ACPI_PROCESSOR
+ default m
help
This driver adds support for ACPI thermal zones. Most mobile and
some desktop systems support ACPI thermal zones. It is HIGHLY
@@ -132,12 +151,16 @@ config ACPI_THERMAL
may be damaged without it.
config ACPI_NUMA
- bool "NUMA support" if NUMA && (IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY && !X86_64)
+ bool "NUMA support"
+ depends on ACPI
+ depends on NUMA
+ depends on !X86_64
default y if IA64_GENERIC || IA64_SGI_SN2
config ACPI_ASUS
tristate "ASUS/Medion Laptop Extras"
- depends on X86 && ACPI && !ACPI_HT_ONLY
+ depends on X86 && ACPI
+ default m
---help---
This driver provides support for extra features of ACPI-compatible
ASUS laptops. As some of Medion laptops are made by ASUS, it may also
@@ -162,7 +185,8 @@ config ACPI_ASUS
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
- depends on X86 && ACPI && !ACPI_HT_ONLY
+ depends on X86 && ACPI
+ default m
---help---
This driver adds support for access to certain system settings
on "legacy free" Toshiba laptops. These laptops can be recognized by
@@ -188,7 +212,9 @@ config ACPI_TOSHIBA
config ACPI_DEBUG
bool "Debug Statements"
- depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
+ depends on ACPI
+ depends on !IA64_SGI_SN
+ default n
help
The ACPI driver can optionally report errors with a great deal
of verbosity. Saying Y enables these statements. This will increase
@@ -196,17 +222,19 @@ config ACPI_DEBUG
config ACPI_BUS
bool
- depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
+ depends on ACPI
+ depends on !IA64_SGI_SN
default y
config ACPI_INTERPRETER
bool
- depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
+ depends on ACPI
+ depends on !IA64_SGI_SN
default y
config ACPI_EC
bool
- depends on X86 && ACPI && !ACPI_HT_ONLY
+ depends on X86 && ACPI
default y
help
This driver is required on some systems for the proper operation of
@@ -215,17 +243,20 @@ config ACPI_EC
config ACPI_POWER
bool
- depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
+ depends on ACPI
+ depends on !IA64_SGI_SN
default y
config ACPI_PCI
bool
- depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
+ depends on ACPI
+ depends on !IA64_SGI_SN
default PCI
config ACPI_SYSTEM
bool
- depends on IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY
+ depends on ACPI
+ depends on !IA64_SGI_SN
default y
help
This driver will enable your system to shut down using ACPI, and
@@ -233,7 +264,8 @@ config ACPI_SYSTEM
config ACPI_EFI
bool
- depends on IA64 && (!IA64_HP_SIM || IA64_SGI_SN)
+ depends on ACPI
+ depends on IA64
default y
endmenu
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index f5f7c06e2a51..d16d4b876ad6 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -12,12 +12,13 @@ endif
EXTRA_CFLAGS += $(ACPI_CFLAGS)
-obj-y := acpi_ksyms.o
+obj-$(CONFIG_ACPI) := acpi_ksyms.o
#
# ACPI Boot-Time Table Parsing
#
-obj-$(CONFIG_ACPI_BOOT) += tables.o blacklist.o
+obj-$(CONFIG_ACPI_BOOT) += tables.o
+obj-$(CONFIG_ACPI) += blacklist.o
#
# ACPI Core Subsystem (Interpreter)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index fd9b9419d9d6..09087bd4a00d 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -691,7 +691,7 @@ static int __init acpi_init (void)
acpi_set_debug(ACPI_DEBUG_LOW);
if (acpi_disabled) {
- printk(KERN_INFO PREFIX "Disabled via command line (acpi=off)\n");
+ printk(KERN_INFO PREFIX "Interpreter disabled.\n");
return -ENODEV;
}
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 233f8e3579df..efd62993e875 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -96,10 +96,11 @@ acpi_table_print (
else
name = header->signature;
- printk(KERN_INFO PREFIX "%.4s (v%3.3d %6.6s %8.8s %5.5d.%5.5d) @ 0x%p\n",
+ printk(KERN_INFO PREFIX "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n",
name, header->revision, header->oem_id,
- header->oem_table_id, header->oem_revision >> 16,
- header->oem_revision & 0xffff, (void *) phys_addr);
+ header->oem_table_id, header->oem_revision,
+ header->asl_compiler_id, header->asl_compiler_revision,
+ (void *) phys_addr);
}
@@ -219,12 +220,16 @@ acpi_table_compute_checksum (
return (sum & 0xFF);
}
+/*
+ * acpi_get_table_header_early()
+ * for acpi_blacklisted(), acpi_table_get_sdt()
+ */
int __init
acpi_get_table_header_early (
enum acpi_table_id id,
struct acpi_table_header **header)
{
- int i;
+ unsigned int i;
enum acpi_table_id temp_id;
/* DSDT is different from the rest */
@@ -281,7 +286,7 @@ acpi_table_parse_madt_family (
acpi_table_entry_header *entry = NULL;
unsigned long count = 0;
unsigned long madt_end = 0;
- int i = 0;
+ unsigned int i = 0;
if (!handler)
return -EINVAL;
@@ -343,7 +348,7 @@ acpi_table_parse (
acpi_table_handler handler)
{
int count = 0;
- int i = 0;
+ unsigned int i = 0;
if (!handler)
return -EINVAL;
@@ -364,7 +369,7 @@ acpi_table_get_sdt (
struct acpi_table_rsdp *rsdp)
{
struct acpi_table_header *header = NULL;
- int i, id = 0;
+ unsigned int i, id = 0;
if (!rsdp)
return -EINVAL;
@@ -550,7 +555,7 @@ acpi_table_init (void)
return -ENODEV;
}
- printk(KERN_INFO PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n",
+ printk(KERN_INFO PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n",
rsdp->revision, rsdp->oem_id, (void *) rsdp_phys);
if (rsdp->revision < 2)
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
index 0f158dc1615e..350048b1f39e 100644
--- a/include/asm-i386/acpi.h
+++ b/include/asm-i386/acpi.h
@@ -106,30 +106,22 @@
:"0"(n_hi), "1"(n_lo))
-#ifdef CONFIG_ACPI_HT_ONLY
-extern int acpi_lapic;
-#define acpi_ioapic 0
+#if defined(CONFIG_ACPI_BOOT) && defined(CONFIG_X86_LOCAL_APIC)
+ extern int acpi_lapic;
#else
-#ifndef CONFIG_ACPI_BOOT
-#define acpi_lapic 0
-#define acpi_ioapic 0
-#else
-#ifdef CONFIG_X86_LOCAL_APIC
-extern int acpi_lapic;
-#else
-#define acpi_lapic 0
+ #define acpi_lapic 0
#endif
-#ifdef CONFIG_X86_IO_APIC
-extern int acpi_ioapic;
+
+#if defined(CONFIG_ACPI_BOOT) && defined(CONFIG_X86_IO_APIC)
+ extern int acpi_ioapic;
#else
-#define acpi_ioapic 0
-#endif
+ #define acpi_ioapic 0
#endif
+#ifdef CONFIG_ACPI_BOOT
/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
#define FIX_ACPI_PAGES 4
-
-#endif /*CONFIG_ACPI_BOOT*/
+#endif
#ifdef CONFIG_ACPI_SLEEP
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 0869bc8e6a2f..4486e056d57f 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -268,6 +268,16 @@ retry:
printk("VFS: Cannot open root device \"%s\" or %s\n",
root_device_name, b);
printk("Please append a correct \"root=\" boot option\n");
+#ifdef __i386__
+ {
+ extern void dmi_dump_system(void);
+ printk ("You may want to retry boot with pci=noacpi, "
+ "acpi=ht, or acpi=off on the command line.\n");
+ printk ("If one of them helps please report it with "
+ "the following lines:\n");
+ dmi_dump_system();
+ }
+#endif
panic("VFS: Unable to mount root fs on %s", b);
}
panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b));