RHEL4/kernel/printk.c
<<
>>
Prefs
   1/*
   2 *  linux/kernel/printk.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 *
   6 * Modified to make sys_syslog() more flexible: added commands to
   7 * return the last 4k of kernel messages, regardless of whether
   8 * they've been read or not.  Added option to suppress kernel printk's
   9 * to the console.  Added hook for sending the console messages
  10 * elsewhere, in preparation for a serial line console (someday).
  11 * Ted Ts'o, 2/11/93.
  12 * Modified for sysctl support, 1/8/97, Chris Horn.
  13 * Fixed SMP synchronization, 08/08/99, Manfred Spraul 
  14 *     manfreds@colorfullife.com
  15 * Rewrote bits to get rid of console_lock
  16 *      01Mar01 Andrew Morton <andrewm@uow.edu.au>
  17 */
  18
  19#include <linux/kernel.h>
  20#include <linux/mm.h>
  21#include <linux/tty.h>
  22#include <linux/tty_driver.h>
  23#include <linux/smp_lock.h>
  24#include <linux/console.h>
  25#include <linux/init.h>
  26#include <linux/module.h>
  27#include <linux/interrupt.h>                    /* For in_interrupt() */
  28#include <linux/config.h>
  29#include <linux/delay.h>
  30#include <linux/smp.h>
  31#include <linux/security.h>
  32#include <linux/bootmem.h>
  33
  34#include <asm/uaccess.h>
  35
  36#define __LOG_BUF_LEN   (1 << CONFIG_LOG_BUF_SHIFT)
  37
  38/* printk's without a loglevel use this.. */
  39#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
  40
  41/* We show everything that is MORE important than this.. */
  42#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
  43#define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */
  44
  45DECLARE_WAIT_QUEUE_HEAD(log_wait);
  46
  47int console_printk[4] = {
  48        DEFAULT_CONSOLE_LOGLEVEL,       /* console_loglevel */
  49        DEFAULT_MESSAGE_LOGLEVEL,       /* default_message_loglevel */
  50        MINIMUM_CONSOLE_LOGLEVEL,       /* minimum_console_loglevel */
  51        DEFAULT_CONSOLE_LOGLEVEL,       /* default_console_loglevel */
  52};
  53
  54EXPORT_SYMBOL(console_printk);
  55
  56int oops_in_progress;
  57
  58/*
  59 * console_sem protects the console_drivers list, and also
  60 * provides serialisation for access to the entire console
  61 * driver system.
  62 */
  63static DECLARE_MUTEX(console_sem);
  64struct console *console_drivers;
  65/*
  66 * This is used for debugging the mess that is the VT code by
  67 * keeping track if we have the console semaphore held. It's
  68 * definitely not the perfect debug tool (we don't know if _WE_
  69 * hold it are racing, but it helps tracking those weird code
  70 * path in the console code where we end up in places I want
  71 * locked without the console sempahore held
  72 */
  73static int console_locked;
  74
  75/*
  76 * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars
  77 * It is also used in interesting ways to provide interlocking in
  78 * release_console_sem().
  79 */
  80static spinlock_t logbuf_lock = SPIN_LOCK_UNLOCKED;
  81
  82static char __log_buf[__LOG_BUF_LEN];
  83static char *log_buf = __log_buf;
  84static int log_buf_len = __LOG_BUF_LEN;
  85
  86#define LOG_BUF_MASK    (log_buf_len-1)
  87#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
  88
  89/*
  90 * The indices into log_buf are not constrained to log_buf_len - they
  91 * must be masked before subscripting
  92 */
  93static unsigned long log_start; /* Index into log_buf: next char to be read by syslog() */
  94static unsigned long con_start; /* Index into log_buf: next char to be sent to consoles */
  95static unsigned long log_end;   /* Index into log_buf: most-recently-written-char + 1 */
  96static unsigned long logged_chars; /* Number of chars produced since last read+clear operation */
  97
  98/*
  99 *      Array of consoles built from command line options (console=)
 100 */
 101struct console_cmdline
 102{
 103        char    name[8];                        /* Name of the driver       */
 104        int     index;                          /* Minor dev. to use        */
 105        char    *options;                       /* Options for the driver   */
 106};
 107
 108#define MAX_CMDLINECONSOLES 8
 109
 110static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
 111static int preferred_console = -1;
 112
 113/* Flag: console code may call schedule() */
 114static int console_may_schedule;
 115
 116/*
 117 *      Setup a list of consoles. Called from init/main.c
 118 */
 119static int __init console_setup(char *str)
 120{
 121        char name[sizeof(console_cmdline[0].name)];
 122        char *s, *options;
 123        int idx;
 124
 125        /*
 126         *      Decode str into name, index, options.
 127         */
 128        if (str[0] >= '0' && str[0] <= '9') {
 129                strcpy(name, "ttyS");
 130                strncpy(name + 4, str, sizeof(name) - 5);
 131        } else
 132                strncpy(name, str, sizeof(name) - 1);
 133        name[sizeof(name) - 1] = 0;
 134        if ((options = strchr(str, ',')) != NULL)
 135                *(options++) = 0;
 136#ifdef __sparc__
 137        if (!strcmp(str, "ttya"))
 138                strcpy(name, "ttyS0");
 139        if (!strcmp(str, "ttyb"))
 140                strcpy(name, "ttyS1");
 141#endif
 142        for(s = name; *s; s++)
 143                if (*s >= '0' && *s <= '9')
 144                        break;
 145        idx = simple_strtoul(s, NULL, 10);
 146        *s = 0;
 147
 148        add_preferred_console(name, idx, options);
 149        return 1;
 150}
 151
 152__setup("console=", console_setup);
 153
 154/**
 155 * add_preferred_console - add a device to the list of preferred consoles.
 156 *
 157 * The last preferred console added will be used for kernel messages
 158 * and stdin/out/err for init.  Normally this is used by console_setup
 159 * above to handle user-supplied console arguments; however it can also
 160 * be used by arch-specific code either to override the user or more
 161 * commonly to provide a default console (ie from PROM variables) when
 162 * the user has not supplied one.
 163 */
 164int __init add_preferred_console(char *name, int idx, char *options)
 165{
 166        struct console_cmdline *c;
 167        int i;
 168
 169        /*
 170         *      See if this tty is not yet registered, and
 171         *      if we have a slot free.
 172         */
 173        for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
 174                if (strcmp(console_cmdline[i].name, name) == 0 &&
 175                          console_cmdline[i].index == idx) {
 176                                preferred_console = i;
 177                                return 0;
 178                }
 179        if (i == MAX_CMDLINECONSOLES)
 180                return -E2BIG;
 181        preferred_console = i;
 182        c = &console_cmdline[i];
 183        memcpy(c->name, name, sizeof(c->name));
 184        c->name[sizeof(c->name) - 1] = 0;
 185        c->options = options;
 186        c->index = idx;
 187        return 0;
 188}
 189
 190static int __init log_buf_len_setup(char *str)
 191{
 192        unsigned long size = memparse(str, &str);
 193        unsigned long flags;
 194
 195        if (size)
 196                size = roundup_pow_of_two(size);
 197        if (size > log_buf_len) {
 198                unsigned long start, dest_idx, offset;
 199                char * new_log_buf;
 200
 201                new_log_buf = alloc_bootmem(size);
 202                if (!new_log_buf) {
 203                        printk("log_buf_len: allocation failed\n");
 204                        goto out;
 205                }
 206
 207                spin_lock_irqsave(&logbuf_lock, flags);
 208                log_buf_len = size;
 209                log_buf = new_log_buf;
 210
 211                offset = start = min(con_start, log_start);
 212                dest_idx = 0;
 213                while (start != log_end) {
 214                        log_buf[dest_idx] = __log_buf[start & (__LOG_BUF_LEN - 1)];
 215                        start++;
 216                        dest_idx++;
 217                }
 218                log_start -= offset;
 219                con_start -= offset;
 220                log_end -= offset;
 221                spin_unlock_irqrestore(&logbuf_lock, flags);
 222
 223                printk("log_buf_len: %d\n", log_buf_len);
 224        }
 225out:
 226
 227        return 1;
 228}
 229
 230__setup("log_buf_len=", log_buf_len_setup);
 231
 232/*
 233 * Commands to do_syslog:
 234 *
 235 *      0 -- Close the log.  Currently a NOP.
 236 *      1 -- Open the log. Currently a NOP.
 237 *      2 -- Read from the log.
 238 *      3 -- Read all messages remaining in the ring buffer.
 239 *      4 -- Read and clear all messages remaining in the ring buffer
 240 *      5 -- Clear ring buffer.
 241 *      6 -- Disable printk's to console
 242 *      7 -- Enable printk's to console
 243 *      8 -- Set level of messages printed to console
 244 *      9 -- Return number of unread characters in the log buffer
 245 *     10 -- Return size of the log buffer
 246 */
 247int do_syslog(int type, char __user * buf, int len)
 248{
 249        unsigned long i, j, limit, count;
 250        int do_clear = 0;
 251        char c;
 252        int error = 0;
 253
 254        error = security_syslog(type);
 255        if (error)
 256                return error;
 257
 258        switch (type) {
 259        case 0:         /* Close log */
 260                break;
 261        case 1:         /* Open log */
 262                break;
 263        case 2:         /* Read from log */
 264                error = -EINVAL;
 265                if (!buf || len < 0)
 266                        goto out;
 267                error = 0;
 268                if (!len)
 269                        goto out;
 270                error = verify_area(VERIFY_WRITE,buf,len);
 271                if (error)
 272                        goto out;
 273                error = wait_event_interruptible(log_wait, (log_start - log_end));
 274                if (error)
 275                        goto out;
 276                i = 0;
 277                spin_lock_irq(&logbuf_lock);
 278                while (!error && (log_start != log_end) && i < len) {
 279                        c = LOG_BUF(log_start);
 280                        log_start++;
 281                        spin_unlock_irq(&logbuf_lock);
 282                        error = __put_user(c,buf);
 283                        buf++;
 284                        i++;
 285                        cond_resched();
 286                        spin_lock_irq(&logbuf_lock);
 287                }
 288                spin_unlock_irq(&logbuf_lock);
 289                if (!error)
 290                        error = i;
 291                break;
 292        case 4:         /* Read/clear last kernel messages */
 293                do_clear = 1; 
 294                /* FALL THRU */
 295        case 3:         /* Read last kernel messages */
 296                error = -EINVAL;
 297                if (!buf || len < 0)
 298                        goto out;
 299                error = 0;
 300                if (!len)
 301                        goto out;
 302                error = verify_area(VERIFY_WRITE,buf,len);
 303                if (error)
 304                        goto out;
 305                count = len;
 306                if (count > log_buf_len)
 307                        count = log_buf_len;
 308                spin_lock_irq(&logbuf_lock);
 309                if (count > logged_chars)
 310                        count = logged_chars;
 311                if (do_clear)
 312                        logged_chars = 0;
 313                limit = log_end;
 314                /*
 315                 * __put_user() could sleep, and while we sleep
 316                 * printk() could overwrite the messages 
 317                 * we try to copy to user space. Therefore
 318                 * the messages are copied in reverse. <manfreds>
 319                 */
 320                for(i = 0; i < count && !error; i++) {
 321                        j = limit-1-i;
 322                        if (j + log_buf_len < log_end)
 323                                break;
 324                        c = LOG_BUF(j);
 325                        spin_unlock_irq(&logbuf_lock);
 326                        error = __put_user(c,&buf[count-1-i]);
 327                        cond_resched();
 328                        spin_lock_irq(&logbuf_lock);
 329                }
 330                spin_unlock_irq(&logbuf_lock);
 331                if (error)
 332                        break;
 333                error = i;
 334                if(i != count) {
 335                        int offset = count-error;
 336                        /* buffer overflow during copy, correct user buffer. */
 337                        for(i=0;i<error;i++) {
 338                                if (__get_user(c,&buf[i+offset]) ||
 339                                    __put_user(c,&buf[i])) {
 340                                        error = -EFAULT;
 341                                        break;
 342                                }
 343                                cond_resched();
 344                        }
 345                }
 346                break;
 347        case 5:         /* Clear ring buffer */
 348                logged_chars = 0;
 349                break;
 350        case 6:         /* Disable logging to console */
 351                console_loglevel = minimum_console_loglevel;
 352                break;
 353        case 7:         /* Enable logging to console */
 354                console_loglevel = default_console_loglevel;
 355                break;
 356        case 8:         /* Set level of messages printed to console */
 357                error = -EINVAL;
 358                if (len < 1 || len > 8)
 359                        goto out;
 360                if (len < minimum_console_loglevel)
 361                        len = minimum_console_loglevel;
 362                console_loglevel = len;
 363                error = 0;
 364                break;
 365        case 9:         /* Number of chars in the log buffer */
 366                error = log_end - log_start;
 367                break;
 368        case 10:        /* Size of the log buffer */
 369                error = log_buf_len;
 370                break;
 371        default:
 372                error = -EINVAL;
 373                break;
 374        }
 375out:
 376        return error;
 377}
 378
 379asmlinkage long sys_syslog(int type, char __user * buf, int len)
 380{
 381        return do_syslog(type, buf, len);
 382}
 383
 384/*
 385 * Crashdump special routine. Don't print to global log_buf, just to the
 386 * actual console device(s).
 387 */
 388static void crashdump_call_console_drivers(const char *buf, unsigned long len)
 389{
 390        struct console *con;
 391
 392        for (con = console_drivers; con; con = con->next) {
 393                if ((con->flags & CON_ENABLED) && con->write)
 394                        con->write(con, buf, len);
 395        }
 396}
 397
 398/*
 399 * Call the console drivers on a range of log_buf
 400 */
 401static void __call_console_drivers(unsigned long start, unsigned long end)
 402{
 403        struct console *con;
 404
 405        for (con = console_drivers; con; con = con->next) {
 406                if ((con->flags & CON_ENABLED) && con->write)
 407                        con->write(con, &LOG_BUF(start), end - start);
 408        }
 409}
 410
 411/*
 412 * Write out chars from start to end - 1 inclusive
 413 */
 414static void _call_console_drivers(unsigned long start,
 415                                unsigned long end, int msg_log_level)
 416{
 417        if (msg_log_level < console_loglevel &&
 418                        console_drivers && start != end) {
 419                if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) {
 420                        /* wrapped write */
 421                        __call_console_drivers(start & LOG_BUF_MASK,
 422                                                log_buf_len);
 423                        __call_console_drivers(0, end & LOG_BUF_MASK);
 424                } else {
 425                        __call_console_drivers(start, end);
 426                }
 427        }
 428}
 429
 430/*
 431 * Call the console drivers, asking them to write out
 432 * log_buf[start] to log_buf[end - 1].
 433 * The console_sem must be held.
 434 */
 435static void call_console_drivers(unsigned long start, unsigned long end)
 436{
 437        unsigned long cur_index, start_print;
 438        static int msg_level = -1;
 439
 440        if (((long)(start - end)) > 0)
 441                BUG();
 442
 443        cur_index = start;
 444        start_print = start;
 445        while (cur_index != end) {
 446                if (    msg_level < 0 &&
 447                        ((end - cur_index) > 2) &&
 448                        LOG_BUF(cur_index + 0) == '<' &&
 449                        LOG_BUF(cur_index + 1) >= '0' &&
 450                        LOG_BUF(cur_index + 1) <= '7' &&
 451                        LOG_BUF(cur_index + 2) == '>')
 452                {
 453                        msg_level = LOG_BUF(cur_index + 1) - '0';
 454                        cur_index += 3;
 455                        start_print = cur_index;
 456                }
 457                while (cur_index != end) {
 458                        char c = LOG_BUF(cur_index);
 459                        cur_index++;
 460
 461                        if (c == '\n') {
 462                                if (msg_level < 0) {
 463                                        /*
 464                                         * printk() has already given us loglevel tags in
 465                                         * the buffer.  This code is here in case the
 466                                         * log buffer has wrapped right round and scribbled
 467                                         * on those tags
 468                                         */
 469                                        msg_level = default_message_loglevel;
 470                                }
 471                                _call_console_drivers(start_print, cur_index, msg_level);
 472                                msg_level = -1;
 473                                start_print = cur_index;
 474                                break;
 475                        }
 476                }
 477        }
 478        _call_console_drivers(start_print, end, msg_level);
 479}
 480
 481static void emit_log_char(char c)
 482{
 483        LOG_BUF(log_end) = c;
 484        log_end++;
 485        if (log_end - log_start > log_buf_len)
 486                log_start = log_end - log_buf_len;
 487        if (log_end - con_start > log_buf_len)
 488                con_start = log_end - log_buf_len;
 489        if (logged_chars < log_buf_len)
 490                logged_chars++;
 491}
 492
 493/*
 494 * Zap console related locks when oopsing. Only zap at most once
 495 * every 10 seconds, to leave time for slow consoles to print a
 496 * full oops.
 497 */
 498static void zap_locks(void)
 499{
 500        static unsigned long oops_timestamp;
 501
 502        if (time_after_eq(jiffies, oops_timestamp) &&
 503                        !time_after(jiffies, oops_timestamp + 30*HZ))
 504                return;
 505
 506        oops_timestamp = jiffies;
 507
 508        /* If a crash is occurring, make sure we can't deadlock */
 509        spin_lock_init(&logbuf_lock);
 510        /* And make sure that we print immediately */
 511        init_MUTEX(&console_sem);
 512}
 513
 514/*
 515 * This is printk.  It can be called from any context.  We want it to work.
 516 * 
 517 * We try to grab the console_sem.  If we succeed, it's easy - we log the output and
 518 * call the console drivers.  If we fail to get the semaphore we place the output
 519 * into the log buffer and return.  The current holder of the console_sem will
 520 * notice the new output in release_console_sem() and will send it to the
 521 * consoles before releasing the semaphore.
 522 *
 523 * One effect of this deferred printing is that code which calls printk() and
 524 * then changes console_loglevel may break. This is because console_loglevel
 525 * is inspected when the actual printing occurs.
 526 */
 527asmlinkage int printk(const char *fmt, ...)
 528{
 529        va_list args;
 530        int r;
 531
 532        va_start(args, fmt);
 533        r = vprintk(fmt, args);
 534        va_end(args);
 535
 536        return r;
 537}
 538
 539asmlinkage int vprintk(const char *fmt, va_list args)
 540{
 541        unsigned long flags;
 542        int printed_len;
 543        char *p;
 544        static char printk_buf[1024];
 545        static int log_level_unknown = 1;
 546
 547        if (unlikely(oops_in_progress))
 548                zap_locks();
 549
 550        /* This stops the holder of console_sem just where we want him */
 551        spin_lock_irqsave(&logbuf_lock, flags);
 552
 553        /* Emit the output into the temporary buffer */
 554        printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
 555
 556        if (unlikely(crashdump_mode())) {
 557                crashdump_call_console_drivers(printk_buf, printed_len);
 558                spin_unlock_irqrestore(&logbuf_lock, flags);
 559                goto out;
 560        }
 561
 562        /*
 563         * Copy the output into log_buf.  If the caller didn't provide
 564         * appropriate log level tags, we insert them here
 565         */
 566        for (p = printk_buf; *p; p++) {
 567                if (log_level_unknown) {
 568                        if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') {
 569                                emit_log_char('<');
 570                                emit_log_char(default_message_loglevel + '0');
 571                                emit_log_char('>');
 572                        }
 573                        log_level_unknown = 0;
 574                }
 575                emit_log_char(*p);
 576                if (*p == '\n')
 577                        log_level_unknown = 1;
 578        }
 579
 580        if (!cpu_online(smp_processor_id()) &&
 581            system_state != SYSTEM_RUNNING) {
 582                /*
 583                 * Some console drivers may assume that per-cpu resources have
 584                 * been allocated.  So don't allow them to be called by this
 585                 * CPU until it is officially up.  We shouldn't be calling into
 586                 * random console drivers on a CPU which doesn't exist yet..
 587                 */
 588                spin_unlock_irqrestore(&logbuf_lock, flags);
 589                goto out;
 590        }
 591        if (!down_trylock(&console_sem)) {
 592                console_locked = 1;
 593                /*
 594                 * We own the drivers.  We can drop the spinlock and let
 595                 * release_console_sem() print the text
 596                 */
 597                spin_unlock_irqrestore(&logbuf_lock, flags);
 598                console_may_schedule = 0;
 599                release_console_sem();
 600        } else {
 601                /*
 602                 * Someone else owns the drivers.  We drop the spinlock, which
 603                 * allows the semaphore holder to proceed and to call the
 604                 * console drivers with the output which we just produced.
 605                 */
 606                spin_unlock_irqrestore(&logbuf_lock, flags);
 607        }
 608out:
 609        return printed_len;
 610}
 611EXPORT_SYMBOL(printk);
 612EXPORT_SYMBOL(vprintk);
 613
 614/**
 615 * acquire_console_sem - lock the console system for exclusive use.
 616 *
 617 * Acquires a semaphore which guarantees that the caller has
 618 * exclusive access to the console system and the console_drivers list.
 619 *
 620 * Can sleep, returns nothing.
 621 */
 622void acquire_console_sem(void)
 623{
 624        if (in_interrupt())
 625                BUG();
 626        down(&console_sem);
 627        console_locked = 1;
 628        console_may_schedule = 1;
 629}
 630EXPORT_SYMBOL(acquire_console_sem);
 631
 632int is_console_locked(void)
 633{
 634        return console_locked;
 635}
 636EXPORT_SYMBOL(is_console_locked);
 637
 638/**
 639 * release_console_sem - unlock the console system
 640 *
 641 * Releases the semaphore which the caller holds on the console system
 642 * and the console driver list.
 643 *
 644 * While the semaphore was held, console output may have been buffered
 645 * by printk().  If this is the case, release_console_sem() emits
 646 * the output prior to releasing the semaphore.
 647 *
 648 * If there is output waiting for klogd, we wake it up.
 649 *
 650 * release_console_sem() may be called from any context.
 651 */
 652void release_console_sem(void)
 653{
 654        unsigned long flags;
 655        unsigned long _con_start, _log_end;
 656        unsigned long wake_klogd = 0;
 657
 658        for ( ; ; ) {
 659                spin_lock_irqsave(&logbuf_lock, flags);
 660                wake_klogd |= log_start - log_end;
 661                if (con_start == log_end)
 662                        break;                  /* Nothing to print */
 663                _con_start = con_start;
 664                _log_end = log_end;
 665                con_start = log_end;            /* Flush */
 666                spin_unlock_irqrestore(&logbuf_lock, flags);
 667                call_console_drivers(_con_start, _log_end);
 668        }
 669        console_locked = 0;
 670        console_may_schedule = 0;
 671        up(&console_sem);
 672        spin_unlock_irqrestore(&logbuf_lock, flags);
 673        if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait))
 674                wake_up_interruptible(&log_wait);
 675}
 676EXPORT_SYMBOL(release_console_sem);
 677
 678/** console_conditional_schedule - yield the CPU if required
 679 *
 680 * If the console code is currently allowed to sleep, and
 681 * if this CPU should yield the CPU to another task, do
 682 * so here.
 683 *
 684 * Must be called within acquire_console_sem().
 685 */
 686void console_conditional_schedule(void)
 687{
 688        if (console_may_schedule && need_resched()) {
 689                set_current_state(TASK_RUNNING);
 690                schedule();
 691        }
 692}
 693EXPORT_SYMBOL(console_conditional_schedule);
 694
 695void console_print(const char *s)
 696{
 697        printk(KERN_EMERG "%s", s);
 698}
 699EXPORT_SYMBOL(console_print);
 700
 701void console_unblank(void)
 702{
 703        struct console *c;
 704
 705        /*
 706         * Try to get the console semaphore. If someone else owns it
 707         * we have to return without unblanking because console_unblank
 708         * may be called in interrupt context.
 709         */
 710        if (down_trylock(&console_sem) != 0)
 711                return;
 712        console_locked = 1;
 713        console_may_schedule = 0;
 714        for (c = console_drivers; c != NULL; c = c->next)
 715                if ((c->flags & CON_ENABLED) && c->unblank)
 716                        c->unblank();
 717        release_console_sem();
 718}
 719EXPORT_SYMBOL(console_unblank);
 720
 721/*
 722 * Return the console tty driver structure and its associated index
 723 */
 724struct tty_driver *console_device(int *index)
 725{
 726        struct console *c;
 727        struct tty_driver *driver = NULL;
 728
 729        acquire_console_sem();
 730        for (c = console_drivers; c != NULL; c = c->next) {
 731                if (!c->device)
 732                        continue;
 733                driver = c->device(c, index);
 734                if (driver)
 735                        break;
 736        }
 737        release_console_sem();
 738        return driver;
 739}
 740
 741/*
 742 * Prevent further output on the passed console device so that (for example)
 743 * serial drivers can disable console output before suspending a port, and can
 744 * re-enable output afterwards.
 745 */
 746void console_stop(struct console *console)
 747{
 748        acquire_console_sem();
 749        console->flags &= ~CON_ENABLED;
 750        release_console_sem();
 751}
 752EXPORT_SYMBOL(console_stop);
 753
 754void console_start(struct console *console)
 755{
 756        acquire_console_sem();
 757        console->flags |= CON_ENABLED;
 758        release_console_sem();
 759}
 760EXPORT_SYMBOL(console_start);
 761
 762/*
 763 * The console driver calls this routine during kernel initialization
 764 * to register the console printing procedure with printk() and to
 765 * print any messages that were printed by the kernel before the
 766 * console driver was initialized.
 767 */
 768void register_console(struct console * console)
 769{
 770        int     i;
 771        unsigned long flags;
 772
 773        /*
 774         *      See if we want to use this console driver. If we
 775         *      didn't select a console we take the first one
 776         *      that registers here.
 777         */
 778        if (preferred_console < 0) {
 779                if (console->index < 0)
 780                        console->index = 0;
 781                if (console->setup == NULL ||
 782                    console->setup(console, NULL) == 0) {
 783                        console->flags |= CON_ENABLED | CON_CONSDEV;
 784                        preferred_console = 0;
 785                }
 786        }
 787
 788        /*
 789         *      See if this console matches one we selected on
 790         *      the command line.
 791         */
 792        for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) {
 793                if (strcmp(console_cmdline[i].name, console->name) != 0)
 794                        continue;
 795                if (console->index >= 0 &&
 796                    console->index != console_cmdline[i].index)
 797                        continue;
 798                if (console->index < 0)
 799                        console->index = console_cmdline[i].index;
 800                if (console->setup &&
 801                    console->setup(console, console_cmdline[i].options) != 0)
 802                        break;
 803                console->flags |= CON_ENABLED;
 804                console->index = console_cmdline[i].index;
 805                if (i == preferred_console)
 806                        console->flags |= CON_CONSDEV;
 807                break;
 808        }
 809
 810        if (!(console->flags & CON_ENABLED))
 811                return;
 812
 813        /*
 814         *      Put this console in the list - keep the
 815         *      preferred driver at the head of the list.
 816         */
 817        acquire_console_sem();
 818        if ((console->flags & CON_CONSDEV) || console_drivers == NULL) {
 819                console->next = console_drivers;
 820                console_drivers = console;
 821        } else {
 822                console->next = console_drivers->next;
 823                console_drivers->next = console;
 824        }
 825        if (console->flags & CON_PRINTBUFFER) {
 826                /*
 827                 * release_console_sem() will print out the buffered messages
 828                 * for us.
 829                 */
 830                spin_lock_irqsave(&logbuf_lock, flags);
 831                con_start = log_start;
 832                spin_unlock_irqrestore(&logbuf_lock, flags);
 833        }
 834        release_console_sem();
 835}
 836EXPORT_SYMBOL(register_console);
 837
 838int unregister_console(struct console * console)
 839{
 840        struct console *a,*b;
 841        int res = 1;
 842
 843        acquire_console_sem();
 844        if (console_drivers == console) {
 845                console_drivers=console->next;
 846                res = 0;
 847        } else {
 848                for (a=console_drivers->next, b=console_drivers ;
 849                     a; b=a, a=b->next) {
 850                        if (a == console) {
 851                                b->next = a->next;
 852                                res = 0;
 853                                break;
 854                        }  
 855                }
 856        }
 857        
 858        /* If last console is removed, we re-enable picking the first
 859         * one that gets registered. Without that, pmac early boot console
 860         * would prevent fbcon from taking over.
 861         */
 862        if (console_drivers == NULL)
 863                preferred_console = -1;
 864                
 865
 866        release_console_sem();
 867        return res;
 868}
 869EXPORT_SYMBOL(unregister_console);
 870        
 871/**
 872 * tty_write_message - write a message to a certain tty, not just the console.
 873 *
 874 * This is used for messages that need to be redirected to a specific tty.
 875 * We don't put it into the syslog queue right now maybe in the future if
 876 * really needed.
 877 */
 878void tty_write_message(struct tty_struct *tty, char *msg)
 879{
 880        if (tty && tty->driver->write)
 881                tty->driver->write(tty, 0, msg, strlen(msg));
 882        return;
 883}
 884
 885/*
 886 * printk rate limiting, lifted from the networking subsystem.
 887 *
 888 * This enforces a rate limit: not more than one kernel message
 889 * every printk_ratelimit_jiffies to make a denial-of-service
 890 * attack impossible.
 891 */
 892int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
 893{
 894        static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
 895        static unsigned long toks = 10*5*HZ;
 896        static unsigned long last_msg;
 897        static int missed;
 898        unsigned long flags;
 899        unsigned long now = jiffies;
 900
 901        spin_lock_irqsave(&ratelimit_lock, flags);
 902        toks += now - last_msg;
 903        last_msg = now;
 904        if (toks > (ratelimit_burst * ratelimit_jiffies))
 905                toks = ratelimit_burst * ratelimit_jiffies;
 906        if (toks >= ratelimit_jiffies) {
 907                int lost = missed;
 908                missed = 0;
 909                toks -= ratelimit_jiffies;
 910                spin_unlock_irqrestore(&ratelimit_lock, flags);
 911                if (lost)
 912                        printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
 913                return 1;
 914        }
 915        missed++;
 916        spin_unlock_irqrestore(&ratelimit_lock, flags);
 917        return 0;
 918}
 919EXPORT_SYMBOL(__printk_ratelimit);
 920
 921/* minimum time in jiffies between messages */
 922int printk_ratelimit_jiffies = 5*HZ;
 923
 924/* number of messages we send before ratelimiting */
 925int printk_ratelimit_burst = 10;
 926
 927int printk_ratelimit(void)
 928{
 929        return __printk_ratelimit(printk_ratelimit_jiffies,
 930                                printk_ratelimit_burst);
 931}
 932EXPORT_SYMBOL(printk_ratelimit);
 933