[PATCH] Add printk_timed_ratelimit()
[pandora-kernel.git] / init / main.c
index 628b8e9..36f608a 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>
@@ -41,6 +39,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>
@@ -125,6 +125,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 +163,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 +180,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 +202,8 @@ static int __init obsolete_checksetup(char *line)
                }
                p++;
        } while (p < __setup_end);
-       return 0;
+
+       return had_early_param;
 }
 
 /*
@@ -462,6 +486,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();
@@ -478,6 +503,7 @@ asmlinkage void __init start_kernel(void)
        printk(KERN_NOTICE);
        printk(linux_banner);
        setup_arch(&command_line);
+       unwind_setup();
        setup_per_cpu_areas();
        smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
 
@@ -500,7 +526,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 +599,8 @@ asmlinkage void __init start_kernel(void)
        proc_root_init();
 #endif
        cpuset_init();
+       taskstats_init_early();
+       delayacct_init();
 
        check_bugs();
 
@@ -675,7 +702,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)
@@ -695,6 +722,8 @@ static int init(void * unused)
         */
        child_reaper = current;
 
+       cad_pid = task_pid(current);
+
        smp_prepare_cpus(max_cpus);
 
        do_pre_smp_initcalls();