#include <linux/security.h>
#include <linux/bootmem.h>
#include <linux/vs_base.h>
+#include <linux/syscalls.h>
#include <asm/uaccess.h>
#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() */
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;
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;
error = __put_user(c,buf);
buf++;
i++;
- cond_resched();
spin_lock_irq(&logbuf_lock);
}
spin_unlock_irq(&logbuf_lock);
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);
error = -EFAULT;
break;
}
- cond_resched();
}
}
break;
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
*/
/* 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
*
* 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);
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
* would prevent fbcon from taking over.
*/
if (console_drivers == NULL)
- preferred_console = -1;
+ preferred_console = selected_console;
release_console_sem();
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;
}