Merge branches 'release' and 'dsdt-override' into release
This commit is contained in:
commit
81e242d0ef
15
Documentation/acpi/dsdt-override.txt
Normal file
15
Documentation/acpi/dsdt-override.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
Linux supports two methods of overriding the BIOS DSDT:
|
||||||
|
|
||||||
|
CONFIG_ACPI_CUSTOM_DSDT builds the image into the kernel.
|
||||||
|
|
||||||
|
CONFIG_ACPI_CUSTOM_DSDT_INITRD adds the image to the initrd.
|
||||||
|
|
||||||
|
When to use these methods is described in detail on the
|
||||||
|
Linux/ACPI home page:
|
||||||
|
http://www.lesswatts.org/projects/acpi/overridingDSDT.php
|
||||||
|
|
||||||
|
Note that if both options are used, the DSDT supplied
|
||||||
|
by the INITRD method takes precedence.
|
||||||
|
|
||||||
|
Documentation/initramfs-add-dsdt.sh is provided for convenience
|
||||||
|
for use with the CONFIG_ACPI_CUSTOM_DSDT_INITRD method.
|
43
Documentation/acpi/initramfs-add-dsdt.sh
Executable file
43
Documentation/acpi/initramfs-add-dsdt.sh
Executable file
|
@ -0,0 +1,43 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Adds a DSDT file to the initrd (if it's an initramfs)
|
||||||
|
# first argument is the name of archive
|
||||||
|
# second argument is the name of the file to add
|
||||||
|
# The file will be copied as /DSDT.aml
|
||||||
|
|
||||||
|
# 20060126: fix "Premature end of file" with some old cpio (Roland Robic)
|
||||||
|
# 20060205: this time it should really work
|
||||||
|
|
||||||
|
# check the arguments
|
||||||
|
if [ $# -ne 2 ]; then
|
||||||
|
program_name=$(basename $0)
|
||||||
|
echo "\
|
||||||
|
$program_name: too few arguments
|
||||||
|
Usage: $program_name initrd-name.img DSDT-to-add.aml
|
||||||
|
Adds a DSDT file to an initrd (in initramfs format)
|
||||||
|
|
||||||
|
initrd-name.img: filename of the initrd in initramfs format
|
||||||
|
DSDT-to-add.aml: filename of the DSDT file to add
|
||||||
|
" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# we should check it's an initramfs
|
||||||
|
|
||||||
|
tempcpio=$(mktemp -d)
|
||||||
|
# cleanup on exit, hangup, interrupt, quit, termination
|
||||||
|
trap 'rm -rf $tempcpio' 0 1 2 3 15
|
||||||
|
|
||||||
|
# extract the archive
|
||||||
|
gunzip -c "$1" > "$tempcpio"/initramfs.cpio || exit 1
|
||||||
|
|
||||||
|
# copy the DSDT file at the root of the directory so that we can call it "/DSDT.aml"
|
||||||
|
cp -f "$2" "$tempcpio"/DSDT.aml
|
||||||
|
|
||||||
|
# add the file
|
||||||
|
cd "$tempcpio"
|
||||||
|
(echo DSDT.aml | cpio --quiet -H newc -o -A -O "$tempcpio"/initramfs.cpio) || exit 1
|
||||||
|
cd "$OLDPWD"
|
||||||
|
|
||||||
|
# re-compress the archive
|
||||||
|
gzip -c "$tempcpio"/initramfs.cpio > "$1"
|
||||||
|
|
|
@ -177,6 +177,9 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
|
|
||||||
acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT
|
acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT
|
||||||
|
|
||||||
|
acpi_no_initrd_override [KNL,ACPI]
|
||||||
|
Disable loading custom ACPI tables from the initramfs
|
||||||
|
|
||||||
acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
|
acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
|
||||||
Format: To spoof as Windows 98: ="Microsoft Windows"
|
Format: To spoof as Windows 98: ="Microsoft Windows"
|
||||||
|
|
||||||
|
|
|
@ -276,8 +276,10 @@ config ACPI_CUSTOM_DSDT
|
||||||
depends on !STANDALONE
|
depends on !STANDALONE
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
This option is to load a custom ACPI DSDT
|
This option supports a custom DSDT by linking it into the kernel.
|
||||||
If you don't know what that is, say N.
|
See Documentation/acpi/dsdt-override.txt
|
||||||
|
|
||||||
|
If unsure, say N.
|
||||||
|
|
||||||
config ACPI_CUSTOM_DSDT_FILE
|
config ACPI_CUSTOM_DSDT_FILE
|
||||||
string "Custom DSDT Table file to include"
|
string "Custom DSDT Table file to include"
|
||||||
|
@ -287,6 +289,17 @@ config ACPI_CUSTOM_DSDT_FILE
|
||||||
Enter the full path name to the file which includes the AmlCode
|
Enter the full path name to the file which includes the AmlCode
|
||||||
declaration.
|
declaration.
|
||||||
|
|
||||||
|
config ACPI_CUSTOM_DSDT_INITRD
|
||||||
|
bool "Read Custom DSDT from initramfs"
|
||||||
|
depends on BLK_DEV_INITRD
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This option supports a custom DSDT by optionally loading it from initrd.
|
||||||
|
See Documentation/acpi/dsdt-override.txt
|
||||||
|
|
||||||
|
If you are not using this feature now, but may use it later,
|
||||||
|
it is safe to say Y here.
|
||||||
|
|
||||||
config ACPI_BLACKLIST_YEAR
|
config ACPI_BLACKLIST_YEAR
|
||||||
int "Disable ACPI for systems before Jan 1st this year" if X86_32
|
int "Disable ACPI for systems before Jan 1st this year" if X86_32
|
||||||
default 0
|
default 0
|
||||||
|
|
|
@ -91,6 +91,10 @@ static DEFINE_SPINLOCK(acpi_res_lock);
|
||||||
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
|
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
|
||||||
static char osi_additional_string[OSI_STRING_LENGTH_MAX];
|
static char osi_additional_string[OSI_STRING_LENGTH_MAX];
|
||||||
|
|
||||||
|
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
|
||||||
|
static int acpi_no_initrd_override;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Ode to _OSI(Linux)"
|
* "Ode to _OSI(Linux)"
|
||||||
*
|
*
|
||||||
|
@ -329,6 +333,67 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
|
||||||
|
struct acpi_table_header *acpi_find_dsdt_initrd(void)
|
||||||
|
{
|
||||||
|
struct file *firmware_file;
|
||||||
|
mm_segment_t oldfs;
|
||||||
|
unsigned long len, len2;
|
||||||
|
struct acpi_table_header *dsdt_buffer, *ret = NULL;
|
||||||
|
struct kstat stat;
|
||||||
|
char *ramfs_dsdt_name = "/DSDT.aml";
|
||||||
|
|
||||||
|
printk(KERN_INFO PREFIX "Checking initramfs for custom DSDT");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Never do this at home, only the user-space is allowed to open a file.
|
||||||
|
* The clean way would be to use the firmware loader.
|
||||||
|
* But this code must be run before there is any userspace available.
|
||||||
|
* A static/init firmware infrastructure doesn't exist yet...
|
||||||
|
*/
|
||||||
|
if (vfs_stat(ramfs_dsdt_name, &stat) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
len = stat.size;
|
||||||
|
/* check especially against empty files */
|
||||||
|
if (len <= 4) {
|
||||||
|
printk(KERN_ERR PREFIX "Failed: DSDT only %lu bytes.\n", len);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
firmware_file = filp_open(ramfs_dsdt_name, O_RDONLY, 0);
|
||||||
|
if (IS_ERR(firmware_file)) {
|
||||||
|
printk(KERN_ERR PREFIX "Failed to open %s.\n", ramfs_dsdt_name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
dsdt_buffer = kmalloc(len, GFP_ATOMIC);
|
||||||
|
if (!dsdt_buffer) {
|
||||||
|
printk(KERN_ERR PREFIX "Failed to allocate %lu bytes.\n", len);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
oldfs = get_fs();
|
||||||
|
set_fs(KERNEL_DS);
|
||||||
|
len2 = vfs_read(firmware_file, (char __user *)dsdt_buffer, len,
|
||||||
|
&firmware_file->f_pos);
|
||||||
|
set_fs(oldfs);
|
||||||
|
if (len2 < len) {
|
||||||
|
printk(KERN_ERR PREFIX "Failed to read %lu bytes from %s.\n",
|
||||||
|
len, ramfs_dsdt_name);
|
||||||
|
ACPI_FREE(dsdt_buffer);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
printk(KERN_INFO PREFIX "Found %lu byte DSDT in %s.\n",
|
||||||
|
len, ramfs_dsdt_name);
|
||||||
|
ret = dsdt_buffer;
|
||||||
|
err:
|
||||||
|
filp_close(firmware_file, NULL);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_os_table_override(struct acpi_table_header * existing_table,
|
acpi_os_table_override(struct acpi_table_header * existing_table,
|
||||||
struct acpi_table_header ** new_table)
|
struct acpi_table_header ** new_table)
|
||||||
|
@ -336,17 +401,41 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
|
||||||
if (!existing_table || !new_table)
|
if (!existing_table || !new_table)
|
||||||
return AE_BAD_PARAMETER;
|
return AE_BAD_PARAMETER;
|
||||||
|
|
||||||
|
*new_table = NULL;
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_CUSTOM_DSDT
|
#ifdef CONFIG_ACPI_CUSTOM_DSDT
|
||||||
if (strncmp(existing_table->signature, "DSDT", 4) == 0)
|
if (strncmp(existing_table->signature, "DSDT", 4) == 0)
|
||||||
*new_table = (struct acpi_table_header *)AmlCode;
|
*new_table = (struct acpi_table_header *)AmlCode;
|
||||||
else
|
|
||||||
*new_table = NULL;
|
|
||||||
#else
|
|
||||||
*new_table = NULL;
|
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
|
||||||
|
if ((strncmp(existing_table->signature, "DSDT", 4) == 0) &&
|
||||||
|
!acpi_no_initrd_override) {
|
||||||
|
struct acpi_table_header *initrd_table;
|
||||||
|
|
||||||
|
initrd_table = acpi_find_dsdt_initrd();
|
||||||
|
if (initrd_table)
|
||||||
|
*new_table = initrd_table;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (*new_table != NULL) {
|
||||||
|
printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], "
|
||||||
|
"this is unsafe: tainting kernel\n",
|
||||||
|
existing_table->signature,
|
||||||
|
existing_table->oem_table_id);
|
||||||
|
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
|
||||||
|
}
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
|
||||||
|
int __init acpi_no_initrd_override_setup(char *s)
|
||||||
|
{
|
||||||
|
acpi_no_initrd_override = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
__setup("acpi_no_initrd_override", acpi_no_initrd_override_setup);
|
||||||
|
#endif
|
||||||
|
|
||||||
static irqreturn_t acpi_irq(int irq, void *dev_id)
|
static irqreturn_t acpi_irq(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
u32 handled;
|
u32 handled;
|
||||||
|
|
|
@ -243,6 +243,7 @@ extern enum system_states {
|
||||||
#define TAINT_BAD_PAGE (1<<5)
|
#define TAINT_BAD_PAGE (1<<5)
|
||||||
#define TAINT_USER (1<<6)
|
#define TAINT_USER (1<<6)
|
||||||
#define TAINT_DIE (1<<7)
|
#define TAINT_DIE (1<<7)
|
||||||
|
#define TAINT_OVERRIDDEN_ACPI_TABLE (1<<8)
|
||||||
|
|
||||||
extern void dump_stack(void) __cold;
|
extern void dump_stack(void) __cold;
|
||||||
|
|
||||||
|
|
|
@ -538,7 +538,7 @@ skip:
|
||||||
initrd_end = 0;
|
initrd_end = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init populate_rootfs(void)
|
int __init populate_rootfs(void)
|
||||||
{
|
{
|
||||||
char *err = unpack_to_rootfs(__initramfs_start,
|
char *err = unpack_to_rootfs(__initramfs_start,
|
||||||
__initramfs_end - __initramfs_start, 0);
|
__initramfs_end - __initramfs_start, 0);
|
||||||
|
@ -577,4 +577,10 @@ static int __init populate_rootfs(void)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#ifndef CONFIG_ACPI_CUSTOM_DSDT_INITRD
|
||||||
|
/*
|
||||||
|
* if this option is enabled, populate_rootfs() is called _earlier_ in the
|
||||||
|
* boot sequence. This insures that the ACPI initialisation can find the file.
|
||||||
|
*/
|
||||||
rootfs_initcall(populate_rootfs);
|
rootfs_initcall(populate_rootfs);
|
||||||
|
#endif
|
||||||
|
|
|
@ -102,6 +102,12 @@ static inline void mark_rodata_ro(void) { }
|
||||||
extern void tc_init(void);
|
extern void tc_init(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
|
||||||
|
extern int populate_rootfs(void);
|
||||||
|
#else
|
||||||
|
static inline void populate_rootfs(void) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
enum system_states system_state;
|
enum system_states system_state;
|
||||||
EXPORT_SYMBOL(system_state);
|
EXPORT_SYMBOL(system_state);
|
||||||
|
|
||||||
|
@ -648,6 +654,7 @@ asmlinkage void __init start_kernel(void)
|
||||||
|
|
||||||
check_bugs();
|
check_bugs();
|
||||||
|
|
||||||
|
populate_rootfs(); /* For DSDT override from initramfs */
|
||||||
acpi_early_init(); /* before LAPIC and SMP init */
|
acpi_early_init(); /* before LAPIC and SMP init */
|
||||||
|
|
||||||
/* Do the rest non-__init'ed, we're now alive */
|
/* Do the rest non-__init'ed, we're now alive */
|
||||||
|
|
|
@ -161,7 +161,7 @@ const char *print_tainted(void)
|
||||||
{
|
{
|
||||||
static char buf[20];
|
static char buf[20];
|
||||||
if (tainted) {
|
if (tainted) {
|
||||||
snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c",
|
snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c%c",
|
||||||
tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G',
|
tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G',
|
||||||
tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
|
tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
|
||||||
tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
|
tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
|
||||||
|
@ -169,7 +169,8 @@ const char *print_tainted(void)
|
||||||
tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
|
tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
|
||||||
tainted & TAINT_BAD_PAGE ? 'B' : ' ',
|
tainted & TAINT_BAD_PAGE ? 'B' : ' ',
|
||||||
tainted & TAINT_USER ? 'U' : ' ',
|
tainted & TAINT_USER ? 'U' : ' ',
|
||||||
tainted & TAINT_DIE ? 'D' : ' ');
|
tainted & TAINT_DIE ? 'D' : ' ',
|
||||||
|
tainted & TAINT_OVERRIDDEN_ACPI_TABLE ? 'A' : ' ');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
snprintf(buf, sizeof(buf), "Not tainted");
|
snprintf(buf, sizeof(buf), "Not tainted");
|
||||||
|
|
Loading…
Reference in a new issue