Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
[pandora-kernel.git] / init / main.c
index 628b8e9..036f97c 100644 (file)
@@ -9,8 +9,6 @@
  *  Simplified starting of init:  Michael A. Griffith <grif@acm.org> 
  */
 
-#define __KERNEL_SYSCALLS__
-
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
@@ -31,6 +29,7 @@
 #include <linux/percpu.h>
 #include <linux/kmod.h>
 #include <linux/kernel_stat.h>
+#include <linux/start_kernel.h>
 #include <linux/security.h>
 #include <linux/workqueue.h>
 #include <linux/profile.h>
@@ -41,6 +40,8 @@
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
 #include <linux/efi.h>
+#include <linux/taskstats_kern.h>
+#include <linux/delayacct.h>
 #include <linux/unistd.h>
 #include <linux/rmap.h>
 #include <linux/mempolicy.h>
@@ -49,6 +50,9 @@
 #include <linux/buffer_head.h>
 #include <linux/debug_locks.h>
 #include <linux/lockdep.h>
+#include <linux/utsrelease.h>
+#include <linux/pid_namespace.h>
+#include <linux/compile.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
 #error Sorry, your GCC is too old. It builds incorrect kernels.
 #endif
 
+#if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 0
+#warning gcc-4.1.0 is known to miscompile the kernel.  A different compiler version is recommended.
+#endif
+
 static int init(void *);
 
 extern void init_IRQ(void);
@@ -125,6 +133,18 @@ static char *ramdisk_execute_command;
 /* Setup configured maximum number of CPUs to activate */
 static unsigned int max_cpus = NR_CPUS;
 
+/*
+ * If set, this is an indication to the drivers that reset the underlying
+ * device before going ahead with the initialization otherwise driver might
+ * rely on the BIOS and skip the reset operation.
+ *
+ * This is useful if kernel is booting in an unreliable environment.
+ * For ex. kdump situaiton where previous kernel has crashed, BIOS has been
+ * skipped and devices will be in unknown state.
+ */
+unsigned int reset_devices;
+EXPORT_SYMBOL(reset_devices);
+
 /*
  * Setup routine for controlling SMP activation
  *
@@ -151,6 +171,14 @@ static int __init maxcpus(char *str)
 
 __setup("maxcpus=", maxcpus);
 
+static int __init set_reset_devices(char *str)
+{
+       reset_devices = 1;
+       return 1;
+}
+
+__setup("reset_devices", set_reset_devices);
+
 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
 static const char *panic_later, *panic_param;
@@ -160,16 +188,19 @@ extern struct obs_kernel_param __setup_start[], __setup_end[];
 static int __init obsolete_checksetup(char *line)
 {
        struct obs_kernel_param *p;
+       int had_early_param = 0;
 
        p = __setup_start;
        do {
                int n = strlen(p->str);
                if (!strncmp(line, p->str, n)) {
                        if (p->early) {
-                               /* Already done in parse_early_param?  (Needs
-                                * exact match on param part) */
+                               /* Already done in parse_early_param?
+                                * (Needs exact match on param part).
+                                * Keep iterating, as we can have early
+                                * params and __setups of same names 8( */
                                if (line[n] == '\0' || line[n] == '=')
-                                       return 1;
+                                       had_early_param = 1;
                        } else if (!p->setup_func) {
                                printk(KERN_WARNING "Parameter %s is obsolete,"
                                       " ignored\n", p->str);
@@ -179,7 +210,8 @@ static int __init obsolete_checksetup(char *line)
                }
                p++;
        } while (p < __setup_end);
-       return 0;
+
+       return had_early_param;
 }
 
 /*
@@ -462,6 +494,7 @@ asmlinkage void __init start_kernel(void)
         * Need to run as early as possible, to initialize the
         * lockdep hash:
         */
+       unwind_init();
        lockdep_init();
 
        local_irq_disable();
@@ -476,8 +509,9 @@ asmlinkage void __init start_kernel(void)
        boot_cpu_init();
        page_address_init();
        printk(KERN_NOTICE);
-       printk(linux_banner);
+       printk(linux_banner, UTS_RELEASE, UTS_VERSION);
        setup_arch(&command_line);
+       unwind_setup();
        setup_per_cpu_areas();
        smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
 
@@ -500,7 +534,6 @@ asmlinkage void __init start_kernel(void)
                   __stop___param - __start___param,
                   &unknown_bootoption);
        sort_main_extable();
-       unwind_init();
        trap_init();
        rcu_init();
        init_IRQ();
@@ -574,6 +607,8 @@ asmlinkage void __init start_kernel(void)
        proc_root_init();
 #endif
        cpuset_init();
+       taskstats_init_early();
+       delayacct_init();
 
        check_bugs();
 
@@ -592,8 +627,6 @@ static int __init initcall_debug_setup(char *str)
 }
 __setup("initcall_debug", initcall_debug_setup);
 
-struct task_struct *child_reaper = &init_task;
-
 extern initcall_t __initcall_start[], __initcall_end[];
 
 static void __init do_initcalls(void)
@@ -675,7 +708,7 @@ static void do_pre_smp_initcalls(void)
 static void run_init_process(char *init_filename)
 {
        argv_init[0] = init_filename;
-       execve(init_filename, argv_init, envp_init);
+       kernel_execve(init_filename, argv_init, envp_init);
 }
 
 static int init(void * unused)
@@ -693,7 +726,9 @@ static int init(void * unused)
         * assumptions about where in the task array this
         * can be found.
         */
-       child_reaper = current;
+       init_pid_ns.child_reaper = current;
+
+       cad_pid = task_pid(current);
 
        smp_prepare_cpus(max_cpus);