summaryrefslogtreecommitdiff
path: root/patches
diff options
context:
space:
mode:
authorTobias Powalowski <tobias@T-POWA-LX.(none)>2008-12-25 19:36:38 +0100
committerTobias Powalowski <tobias@T-POWA-LX.(none)>2008-12-25 19:36:38 +0100
commit6d8b768db0b9140a1b9a0e1f2597bddacfd241e1 (patch)
tree903fce39521b9f89aa9c5e87816401e3949ceb9b /patches
parent93ccbf9e986514a4650331152712dc590d68e562 (diff)
'update to new major kernel, patched dsdt patch to work with latest
upstream'
Diffstat (limited to 'patches')
-rw-r--r--patches/acpi-dsdt-initrd-v0.9c-2.6.26.patch325
1 files changed, 325 insertions, 0 deletions
diff --git a/patches/acpi-dsdt-initrd-v0.9c-2.6.26.patch b/patches/acpi-dsdt-initrd-v0.9c-2.6.26.patch
new file mode 100644
index 0000000..1be70f8
--- /dev/null
+++ b/patches/acpi-dsdt-initrd-v0.9c-2.6.26.patch
@@ -0,0 +1,325 @@
+Date: Wed, 19 Mar 2008 23:00:04 +0100
+Subject: [PATCH] ACPI: initramfs DSDT override support
+
+Permits to load of DSDT (the main ACPI table) from initramfs. In case this
+option is selected, the initramfs is parsed at ACPI initialization (very early
+boot time) to look for a file called "DSDT.aml". This aims at allowing users to
+override the DSDT without recompiling the kernel.
+
+Version 0.9 uses a different approach for reading the initramfs which avoids
+using the filesystem infrastructure. It leverages the initramfs unpack code to find
+and unpack the DSDT directly into the memory.
+
+v0.9a: Fix compilation on non-ACPI platforms by René Rebe <rene@exactcode.de>
+v0.9b: Declare more functions __init by Jan Beulich <jbeulich@novell.com>
+v0.9c: Allow root to be / instead of nothing, bug reported by Robert Hampovcan
+
+Signed-off-by: Eric Piel <eric.piel@tremplin-utc.net>
+---
+ Documentation/acpi/dsdt-override.txt | 12 +++-
+ Documentation/acpi/initramfs-add-dsdt.sh | 43 ++++++++++++++
+ Documentation/kernel-parameters.txt | 3 +
+ drivers/acpi/Kconfig | 11 ++++
+ drivers/acpi/osl.c | 24 ++++++++
+ init/initramfs.c | 89 ++++++++++++++++++++++++++++++
+ 6 files changed, 180 insertions(+), 2 deletions(-)
+ create mode 100644 Documentation/acpi/initramfs-add-dsdt.sh
+
+diff --git a/Documentation/acpi/dsdt-override.txt b/Documentation/acpi/dsdt-override.txt
+index febbb1b..5008f25 100644
+--- a/Documentation/acpi/dsdt-override.txt
++++ b/Documentation/acpi/dsdt-override.txt
+@@ -1,7 +1,15 @@
+-Linux supports a method of overriding the BIOS DSDT:
++Linux supports two methods of overriding the BIOS DSDT:
+
+ CONFIG_ACPI_CUSTOM_DSDT builds the image into the kernel.
+
+-When to use this method is described in detail on the
++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.
+diff --git a/Documentation/acpi/initramfs-add-dsdt.sh b/Documentation/acpi/initramfs-add-dsdt.sh
+new file mode 100644
+index 0000000..17ef6e8
+--- /dev/null
++++ b/Documentation/acpi/initramfs-add-dsdt.sh
+@@ -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"
++
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+index e07c432..6849df2 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -172,6 +172,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_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
+ Format: To spoof as Windows 98: ="Microsoft Windows"
+
+diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
+index c52fca8..8df213e 100644
+--- a/drivers/acpi/Kconfig
++++ b/drivers/acpi/Kconfig
+@@ -303,6 +303,17 @@ config ACPI_CUSTOM_DSDT
+ bool
+ default ACPI_CUSTOM_DSDT_FILE != ""
+
++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
+ int "Disable ACPI for systems before Jan 1st this year" if X86_32
+ default 0
+diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
+index 235a138..c75f285 100644
+--- a/drivers/acpi/osl.c
++++ b/drivers/acpi/osl.c
+@@ -96,6 +96,11 @@ static DEFINE_SPINLOCK(acpi_res_lock);
+ #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
+ static char osi_additional_string[OSI_STRING_LENGTH_MAX];
+
++#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
++static __initdata int acpi_no_initrd_override;
++extern struct acpi_table_header *acpi_find_dsdt_initrd(void);
++#endif
++
+ /*
+ * "Ode to _OSI(Linux)"
+ *
+@@ -338,6 +343,16 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
+ if (strncmp(existing_table->signature, "DSDT", 4) == 0)
+ *new_table = (struct acpi_table_header *)AmlCode;
+ #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",
+@@ -348,6 +363,15 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
+ return AE_OK;
+ }
+
++#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
++static 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)
+ {
+ u32 handled;
+diff --git a/init/initramfs.c b/init/initramfs.c
+index 8eeeccb..84f9a01 100644
+--- a/init/initramfs.c
++++ b/init/initramfs.c
+@@ -6,6 +6,9 @@
+ #include <linux/string.h>
+ #include <linux/syscalls.h>
+ #include <linux/utime.h>
++#ifdef ACPI_CONFIG
++#include <acpi/acpi.h>
++#endif
+
+ static __initdata char *message;
+ static void __init error(char *x)
+@@ -90,6 +93,12 @@ static __initdata unsigned long body_len, name_len;
+ static __initdata uid_t uid;
+ static __initdata gid_t gid;
+ static __initdata unsigned rdev;
++#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
++static __initdata char *file_looked_for;
++static __initdata struct acpi_table_header *file_mem;
++#else
++const char *file_looked_for = NULL;
++#endif
+
+ static void __init parse_header(char *s)
+ {
+@@ -123,6 +132,7 @@ static __initdata enum state {
+ SkipIt,
+ GotName,
+ CopyFile,
++ CopyFileMem,
+ GotSymlink,
+ Reset
+ } state, next_state;
+@@ -259,6 +269,54 @@ static void __init clean_path(char *path, mode_t mode)
+
+ static __initdata int wfd;
+
++#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
++static __init int is_file_looked_for(char *filename)
++{
++ char *tmp_collected = collected;
++ if (file_looked_for == NULL)
++ return 0;
++ if (!S_ISREG(mode))
++ return 0;
++ /* remove the leading / */
++ while (*tmp_collected == '/')
++ tmp_collected++;
++ return (strcmp(tmp_collected, file_looked_for) == 0);
++}
++
++static int __init do_copy_mem(void)
++{
++ static void *file_current; /* current position in the memory */
++ if (file_mem == NULL) {
++ if (body_len < 4) { /* check especially against empty files */
++ error("file is less than 4 bytes");
++ return 1;
++ }
++ file_mem = kmalloc(body_len, GFP_ATOMIC);
++ if (!file_mem) {
++ error("failed to allocate enough memory");
++ return 1;
++ }
++ file_current = file_mem;
++ }
++ if (count >= body_len) {
++ memcpy(file_current, victim, body_len);
++ eat(body_len);
++ file_looked_for = NULL; /* don't find files with same name */
++ state = SkipIt;
++ return 0;
++ } else {
++ memcpy(file_current, victim, count);
++ file_current += count;
++ body_len -= count;
++ eat(count);
++ return 1;
++ }
++}
++#else
++static inline int is_file_looked_for(char *filename) {return 0;}
++#define do_copy_mem NULL /* because it is used as a pointer */
++#endif
++
+ static int __init do_name(void)
+ {
+ state = SkipIt;
+@@ -267,6 +325,8 @@ static int __init do_name(void)
+ free_hash();
+ return 0;
+ }
++ if (is_file_looked_for(file_looked_for))
++ state = CopyFileMem;
+ if (dry_run)
+ return 0;
+ clean_path(collected, mode);
+@@ -333,6 +393,7 @@ static __initdata int (*actions[])(void) = {
+ [SkipIt] = do_skip,
+ [GotName] = do_name,
+ [CopyFile] = do_copy,
++ [CopyFileMem] = do_copy_mem,
+ [GotSymlink] = do_symlink,
+ [Reset] = do_reset,
+ };
+@@ -578,3 +639,31 @@ static int __init populate_rootfs(void)
+ return 0;
+ }
+ rootfs_initcall(populate_rootfs);
++
++#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
++struct __init acpi_table_header *acpi_find_dsdt_initrd(void)
++{
++ char *err, *ramfs_dsdt_name = "DSDT.aml";
++
++ printk(KERN_INFO "ACPI: Checking initramfs for custom DSDT\n");
++ file_mem = NULL;
++ file_looked_for = ramfs_dsdt_name;
++ err = unpack_to_rootfs((char *)initrd_start,
++ initrd_end - initrd_start, 1);
++ file_looked_for = NULL;
++
++ if (err) {
++ /*
++ * Even if reading the DSDT file was successful,
++ * we give up if the initramfs cannot be entirely read.
++ */
++ kfree(file_mem);
++ printk(KERN_ERR "ACPI: Aborded because %s.\n", err);
++ return NULL;
++ }
++ if (file_mem)
++ printk(KERN_INFO "ACPI: Found DSDT in %s.\n", ramfs_dsdt_name);
++
++ return file_mem;
++}
++#endif
+--
+1.5.6.4
+