upgrade to linux 2.6.10-1.12_FC2
[linux-2.6.git] / kernel / printk.c
index 01621ff..31e1731 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/security.h>
 #include <linux/bootmem.h>
 #include <linux/vs_base.h>
+#include <linux/syscalls.h>
 
 #include <asm/uaccess.h>
 
@@ -109,6 +110,7 @@ struct console_cmdline
 #define MAX_CMDLINECONSOLES 8
 
 static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
+static int selected_console = -1;
 static int preferred_console = -1;
 
 /* Flag: console code may call schedule() */
@@ -141,7 +143,7 @@ static int __init console_setup(char *str)
                strcpy(name, "ttyS1");
 #endif
        for(s = name; *s; s++)
-               if (*s >= '0' && *s <= '9')
+               if ((*s >= '0' && *s <= '9') || *s == ',')
                        break;
        idx = simple_strtoul(s, NULL, 10);
        *s = 0;
@@ -174,12 +176,12 @@ int __init add_preferred_console(char *name, int idx, char *options)
        for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
                if (strcmp(console_cmdline[i].name, name) == 0 &&
                          console_cmdline[i].index == idx) {
-                               preferred_console = i;
+                               selected_console = i;
                                return 0;
                }
        if (i == MAX_CMDLINECONSOLES)
                return -E2BIG;
-       preferred_console = i;
+       selected_console = i;
        c = &console_cmdline[i];
        memcpy(c->name, name, sizeof(c->name));
        c->name[sizeof(c->name) - 1] = 0;
@@ -286,7 +288,6 @@ int do_syslog(int type, char __user * buf, int len)
                        error = __put_user(c,buf);
                        buf++;
                        i++;
-                       cond_resched();
                        spin_lock_irq(&logbuf_lock);
                }
                spin_unlock_irq(&logbuf_lock);
@@ -328,7 +329,6 @@ int do_syslog(int type, char __user * buf, int len)
                        c = LOG_BUF(j);
                        spin_unlock_irq(&logbuf_lock);
                        error = __put_user(c,&buf[count-1-i]);
-                       cond_resched();
                        spin_lock_irq(&logbuf_lock);
                }
                spin_unlock_irq(&logbuf_lock);
@@ -344,7 +344,6 @@ int do_syslog(int type, char __user * buf, int len)
                                        error = -EFAULT;
                                        break;
                                }
-                               cond_resched();
                        }
                }
                break;
@@ -385,6 +384,20 @@ asmlinkage long sys_syslog(int type, char __user * buf, int len)
        return do_syslog(type, buf, len);
 }
 
+/*
+ * Crashdump special routine. Don't print to global log_buf, just to the
+ * actual console device(s).
+ */
+static void crashdump_call_console_drivers(const char *buf, unsigned long len)
+{
+       struct console *con;
+
+       for (con = console_drivers; con; con = con->next) {
+               if ((con->flags & CON_ENABLED) && con->write)
+                       con->write(con, buf, len);
+       }
+}
+
 /*
  * Call the console drivers on a range of log_buf
  */
@@ -543,6 +556,12 @@ asmlinkage int vprintk(const char *fmt, va_list args)
        /* Emit the output into the temporary buffer */
        printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
 
+       if (unlikely(crashdump_mode())) {
+               crashdump_call_console_drivers(printk_buf, printed_len);
+               spin_unlock_irqrestore(&logbuf_lock, flags);
+               goto out;
+       }
+
        /*
         * Copy the output into log_buf.  If the caller didn't provide
         * appropriate log level tags, we insert them here
@@ -667,12 +686,10 @@ EXPORT_SYMBOL(release_console_sem);
  *
  * Must be called within acquire_console_sem().
  */
-void console_conditional_schedule(void)
+void __sched console_conditional_schedule(void)
 {
-       if (console_may_schedule && need_resched()) {
-               set_current_state(TASK_RUNNING);
-               schedule();
-       }
+       if (console_may_schedule)
+               cond_resched();
 }
 EXPORT_SYMBOL(console_conditional_schedule);
 
@@ -754,6 +771,9 @@ void register_console(struct console * console)
        int     i;
        unsigned long flags;
 
+       if (preferred_console < 0)
+               preferred_console = selected_console;
+
        /*
         *      See if we want to use this console driver. If we
         *      didn't select a console we take the first one
@@ -844,7 +864,7 @@ int unregister_console(struct console * console)
         * would prevent fbcon from taking over.
         */
        if (console_drivers == NULL)
-               preferred_console = -1;
+               preferred_console = selected_console;
                
 
        release_console_sem();
@@ -862,7 +882,7 @@ EXPORT_SYMBOL(unregister_console);
 void tty_write_message(struct tty_struct *tty, char *msg)
 {
        if (tty && tty->driver->write)
-               tty->driver->write(tty, 0, msg, strlen(msg));
+               tty->driver->write(tty, msg, strlen(msg));
        return;
 }