linux-old/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
  30#include <asm/uaccess.h>
  31
  32#if !defined(CONFIG_LOG_BUF_SHIFT) || (CONFIG_LOG_BUF_SHIFT == 0)
  33#if defined(CONFIG_MULTIQUAD) || defined(CONFIG_IA64)
  34#define LOG_BUF_LEN     (65536)
  35#elif defined(CONFIG_ARCH_S390)
  36#define LOG_BUF_LEN     (131072)
  37#elif defined(CONFIG_SMP)
  38#define LOG_BUF_LEN     (32768)
  39#else   
  40#define LOG_BUF_LEN     (16384)                 /* This must be a power of two */
  41#endif
  42#else /* CONFIG_LOG_BUF_SHIFT */
  43#define LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
  44#endif
  45
  46#define LOG_BUF_MASK    (LOG_BUF_LEN-1)
  47
  48#ifndef arch_consoles_callable
  49#define arch_consoles_callable() (1)
  50#endif
  51
  52/* printk's without a loglevel use this.. */
  53#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
  54
  55/* We show everything that is MORE important than this.. */
  56#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
  57#define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */
  58
  59DECLARE_WAIT_QUEUE_HEAD(log_wait);
  60
  61int console_printk[4] = {
  62        DEFAULT_CONSOLE_LOGLEVEL,       /* console_loglevel */
  63        DEFAULT_MESSAGE_LOGLEVEL,       /* default_message_loglevel */
  64        MINIMUM_CONSOLE_LOGLEVEL,       /* minimum_console_loglevel */
  65        DEFAULT_CONSOLE_LOGLEVEL,       /* default_console_loglevel */
  66};
  67
  68int oops_in_progress;
  69
  70/*
  71 * console_sem protects the console_drivers list, and also
  72 * provides serialisation for access to the entire console
  73 * driver system.
  74 */
  75static DECLARE_MUTEX(console_sem);
  76struct console *console_drivers;
  77
  78/*
  79 * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars
  80 * It is also used in interesting ways to provide interlocking in
  81 * release_console_sem().
  82 */
  83static spinlock_t logbuf_lock = SPIN_LOCK_UNLOCKED;
  84
  85static char log_buf[LOG_BUF_LEN];
  86#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
  87
  88/*
  89 * The indices into log_buf are not constrained to LOG_BUF_LEN - they
  90 * must be masked before subscripting
  91 */
  92static unsigned long log_start;                 /* Index into log_buf: next char to be read by syslog() */
  93static unsigned long con_start;                 /* Index into log_buf: next char to be sent to consoles */
  94static unsigned long log_end;                   /* Index into log_buf: most-recently-written-char + 1 */
  95static unsigned long logged_chars;              /* Number of chars produced since last read+clear operation */
  96
  97struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
  98static int selected_console = -1;
  99static int preferred_console = -1;
 100
 101/* Flag: console code may call schedule() */
 102static int console_may_schedule;
 103
 104/*
 105 *      Setup a list of consoles. Called from init/main.c
 106 */
 107static int __init console_setup(char *str)
 108{
 109        struct console_cmdline *c;
 110        char name[sizeof(c->name)];
 111        char *s, *options;
 112        int i, idx;
 113
 114        /*
 115         *      Decode str into name, index, options.
 116         */
 117        if (str[0] >= '0' && str[0] <= '9') {
 118                strcpy(name, "ttyS");
 119                strncpy(name + 4, str, sizeof(name) - 5);
 120        } else
 121                strncpy(name, str, sizeof(name) - 1);
 122        name[sizeof(name) - 1] = 0;
 123        if ((options = strchr(str, ',')) != NULL)
 124                *(options++) = 0;
 125#ifdef __sparc__
 126        if (!strcmp(str, "ttya"))
 127                strcpy(name, "ttyS0");
 128        if (!strcmp(str, "ttyb"))
 129                strcpy(name, "ttyS1");
 130#endif
 131        for(s = name; *s; s++)
 132                if (*s >= '0' && *s <= '9')
 133                        break;
 134        idx = simple_strtoul(s, NULL, 10);
 135        *s = 0;
 136
 137        /*
 138         *      See if this tty is not yet registered, and
 139         *      if we have a slot free.
 140         */
 141        for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
 142                if (strcmp(console_cmdline[i].name, name) == 0 &&
 143                          console_cmdline[i].index == idx) {
 144                                selected_console = i;
 145                                return 1;
 146                }
 147        if (i == MAX_CMDLINECONSOLES)
 148                return 1;
 149        selected_console = i;
 150        c = &console_cmdline[i];
 151        memcpy(c->name, name, sizeof(c->name));
 152        c->options = options;
 153        c->index = idx;
 154        return 1;
 155}
 156
 157__setup("console=", console_setup);
 158
 159/*
 160 * Commands to do_syslog:
 161 *
 162 *      0 -- Close the log.  Currently a NOP.
 163 *      1 -- Open the log. Currently a NOP.
 164 *      2 -- Read from the log.
 165 *      3 -- Read all messages remaining in the ring buffer.
 166 *      4 -- Read and clear all messages remaining in the ring buffer
 167 *      5 -- Clear ring buffer.
 168 *      6 -- Disable printk's to console
 169 *      7 -- Enable printk's to console
 170 *      8 -- Set level of messages printed to console
 171 *      9 -- Return number of unread characters in the log buffer
 172 */
 173int do_syslog(int type, char * buf, int len)
 174{
 175        unsigned long i, j, limit, count;
 176        int do_clear = 0;
 177        char c;
 178        int error = 0;
 179
 180        switch (type) {
 181        case 0:         /* Close log */
 182                break;
 183        case 1:         /* Open log */
 184                break;
 185        case 2:         /* Read from log */
 186                error = -EINVAL;
 187                if (!buf || len < 0)
 188                        goto out;
 189                error = 0;
 190                if (!len)
 191                        goto out;
 192                error = verify_area(VERIFY_WRITE,buf,len);
 193                if (error)
 194                        goto out;
 195                error = wait_event_interruptible(log_wait, (log_start - log_end));
 196                if (error)
 197                        goto out;
 198                i = 0;
 199                spin_lock_irq(&logbuf_lock);
 200                while ((log_start != log_end) && i < len) {
 201                        c = LOG_BUF(log_start);
 202                        log_start++;
 203                        spin_unlock_irq(&logbuf_lock);
 204                        __put_user(c,buf);
 205                        buf++;
 206                        i++;
 207                        spin_lock_irq(&logbuf_lock);
 208                }
 209                spin_unlock_irq(&logbuf_lock);
 210                error = i;
 211                break;
 212        case 4:         /* Read/clear last kernel messages */
 213                do_clear = 1; 
 214                /* FALL THRU */
 215        case 3:         /* Read last kernel messages */
 216                error = -EINVAL;
 217                if (!buf || len < 0)
 218                        goto out;
 219                error = 0;
 220                if (!len)
 221                        goto out;
 222                error = verify_area(VERIFY_WRITE,buf,len);
 223                if (error)
 224                        goto out;
 225                count = len;
 226                if (count > LOG_BUF_LEN)
 227                        count = LOG_BUF_LEN;
 228                spin_lock_irq(&logbuf_lock);
 229                if (count > logged_chars)
 230                        count = logged_chars;
 231                if (do_clear)
 232                        logged_chars = 0;
 233                limit = log_end;
 234                /*
 235                 * __put_user() could sleep, and while we sleep
 236                 * printk() could overwrite the messages 
 237                 * we try to copy to user space. Therefore
 238                 * the messages are copied in reverse. <manfreds>
 239                 */
 240                for(i=0;i < count;i++) {
 241                        j = limit-1-i;
 242                        if (j+LOG_BUF_LEN < log_end)
 243                                break;
 244                        c = LOG_BUF(j);
 245                        spin_unlock_irq(&logbuf_lock);
 246                        __put_user(c,&buf[count-1-i]);
 247                        spin_lock_irq(&logbuf_lock);
 248                }
 249                spin_unlock_irq(&logbuf_lock);
 250                error = i;
 251                if(i != count) {
 252                        int offset = count-error;
 253                        /* buffer overflow during copy, correct user buffer. */
 254                        for(i=0;i<error;i++) {
 255                                __get_user(c,&buf[i+offset]);
 256                                __put_user(c,&buf[i]);
 257                        }
 258                }
 259
 260                break;
 261        case 5:         /* Clear ring buffer */
 262                spin_lock_irq(&logbuf_lock);
 263                logged_chars = 0;
 264                spin_unlock_irq(&logbuf_lock);
 265                break;
 266        case 6:         /* Disable logging to console */
 267                spin_lock_irq(&logbuf_lock);
 268                console_loglevel = minimum_console_loglevel;
 269                spin_unlock_irq(&logbuf_lock);
 270                break;
 271        case 7:         /* Enable logging to console */
 272                spin_lock_irq(&logbuf_lock);
 273                console_loglevel = default_console_loglevel;
 274                spin_unlock_irq(&logbuf_lock);
 275                break;
 276        case 8:         /* Set level of messages printed to console */
 277                error = -EINVAL;
 278                if (len < 1 || len > 8)
 279                        goto out;
 280                if (len < minimum_console_loglevel)
 281                        len = minimum_console_loglevel;
 282                spin_lock_irq(&logbuf_lock);
 283                console_loglevel = len;
 284                spin_unlock_irq(&logbuf_lock);
 285                error = 0;
 286                break;
 287        case 9:         /* Number of chars in the log buffer */
 288                spin_lock_irq(&logbuf_lock);
 289                error = log_end - log_start;
 290                spin_unlock_irq(&logbuf_lock);
 291                break;
 292        default:
 293                error = -EINVAL;
 294                break;
 295        }
 296out:
 297        return error;
 298}
 299
 300asmlinkage long sys_syslog(int type, char * buf, int len)
 301{
 302        if ((type != 3) && !capable(CAP_SYS_ADMIN))
 303                return -EPERM;
 304        return do_syslog(type, buf, len);
 305}
 306
 307/*
 308 * Call the console drivers on a range of log_buf
 309 */
 310static void __call_console_drivers(unsigned long start, unsigned long end)
 311{
 312        struct console *con;
 313
 314        for (con = console_drivers; con; con = con->next) {
 315                if ((con->flags & CON_ENABLED) && con->write)
 316                        con->write(con, &LOG_BUF(start), end - start);
 317        }
 318}
 319
 320/*
 321 * Write out chars from start to end - 1 inclusive
 322 */
 323static void _call_console_drivers(unsigned long start, unsigned long end, int msg_log_level)
 324{
 325        if (msg_log_level < console_loglevel && console_drivers && start != end) {
 326                if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) {
 327                        /* wrapped write */
 328                        __call_console_drivers(start & LOG_BUF_MASK, LOG_BUF_LEN);
 329                        __call_console_drivers(0, end & LOG_BUF_MASK);
 330                } else {
 331                        __call_console_drivers(start, end);
 332                }
 333        }
 334}
 335
 336/*
 337 * Call the console drivers, asking them to write out
 338 * log_buf[start] to log_buf[end - 1].
 339 * The console_sem must be held.
 340 */
 341static void call_console_drivers(unsigned long start, unsigned long end)
 342{
 343        unsigned long cur_index, start_print;
 344        static int msg_level = -1;
 345
 346        if (((long)(start - end)) > 0)
 347                BUG();
 348
 349        cur_index = start;
 350        start_print = start;
 351        while (cur_index != end) {
 352                if (    msg_level < 0 &&
 353                        ((end - cur_index) > 2) &&
 354                        LOG_BUF(cur_index + 0) == '<' &&
 355                        LOG_BUF(cur_index + 1) >= '0' &&
 356                        LOG_BUF(cur_index + 1) <= '7' &&
 357                        LOG_BUF(cur_index + 2) == '>')
 358                {
 359                        msg_level = LOG_BUF(cur_index + 1) - '0';
 360                        cur_index += 3;
 361                        start_print = cur_index;
 362                }
 363                while (cur_index != end) {
 364                        char c = LOG_BUF(cur_index);
 365                        cur_index++;
 366
 367                        if (c == '\n') {
 368                                if (msg_level < 0) {
 369                                        /*
 370                                         * printk() has already given us loglevel tags in
 371                                         * the buffer.  This code is here in case the
 372                                         * log buffer has wrapped right round and scribbled
 373                                         * on those tags
 374                                         */
 375                                        msg_level = default_message_loglevel;
 376                                }
 377                                _call_console_drivers(start_print, cur_index, msg_level);
 378                                msg_level = -1;
 379                                start_print = cur_index;
 380                                break;
 381                        }
 382                }
 383        }
 384        _call_console_drivers(start_print, end, msg_level);
 385}
 386
 387static void emit_log_char(char c)
 388{
 389        LOG_BUF(log_end) = c;
 390        log_end++;
 391        if (log_end - log_start > LOG_BUF_LEN)
 392                log_start = log_end - LOG_BUF_LEN;
 393        if (log_end - con_start > LOG_BUF_LEN)
 394                con_start = log_end - LOG_BUF_LEN;
 395        if (logged_chars < LOG_BUF_LEN)
 396                logged_chars++;
 397}
 398
 399/*
 400 * This is printk.  It can be called from any context.  We want it to work.
 401 * 
 402 * We try to grab the console_sem.  If we succeed, it's easy - we log the output and
 403 * call the console drivers.  If we fail to get the semaphore we place the output
 404 * into the log buffer and return.  The current holder of the console_sem will
 405 * notice the new output in release_console_sem() and will send it to the
 406 * consoles before releasing the semaphore.
 407 *
 408 * One effect of this deferred printing is that code which calls printk() and
 409 * then changes console_loglevel may break. This is because console_loglevel
 410 * is inspected when the actual printing occurs.
 411 */
 412asmlinkage int printk(const char *fmt, ...)
 413{
 414        va_list args;
 415        unsigned long flags;
 416        int printed_len;
 417        char *p;
 418        static char printk_buf[1024];
 419        static int log_level_unknown = 1;
 420
 421        if (oops_in_progress) {
 422                /* If a crash is occurring, make sure we can't deadlock */
 423                spin_lock_init(&logbuf_lock);
 424                /* And make sure that we print immediately */
 425                init_MUTEX(&console_sem);
 426        }
 427
 428        /* This stops the holder of console_sem just where we want him */
 429        spin_lock_irqsave(&logbuf_lock, flags);
 430
 431        /* Emit the output into the temporary buffer */
 432        va_start(args, fmt);
 433        printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
 434        va_end(args);
 435
 436        /*
 437         * Copy the output into log_buf.  If the caller didn't provide
 438         * appropriate log level tags, we insert them here
 439         */
 440        for (p = printk_buf; *p; p++) {
 441                if (log_level_unknown) {
 442                        if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') {
 443                                emit_log_char('<');
 444                                emit_log_char(default_message_loglevel + '0');
 445                                emit_log_char('>');
 446                        }
 447                        log_level_unknown = 0;
 448                }
 449                emit_log_char(*p);
 450                if (*p == '\n')
 451                        log_level_unknown = 1;
 452        }
 453
 454        if (!arch_consoles_callable()) {
 455                /*
 456                 * On some architectures, the consoles are not usable
 457                 * on secondary CPUs early in the boot process.
 458                 */
 459                spin_unlock_irqrestore(&logbuf_lock, flags);
 460                goto out;
 461        }
 462        if (!down_trylock(&console_sem)) {
 463                /*
 464                 * We own the drivers.  We can drop the spinlock and let
 465                 * release_console_sem() print the text
 466                 */
 467                spin_unlock_irqrestore(&logbuf_lock, flags);
 468                console_may_schedule = 0;
 469                release_console_sem();
 470        } else {
 471                /*
 472                 * Someone else owns the drivers.  We drop the spinlock, which
 473                 * allows the semaphore holder to proceed and to call the
 474                 * console drivers with the output which we just produced.
 475                 */
 476                spin_unlock_irqrestore(&logbuf_lock, flags);
 477        }
 478out:
 479        return printed_len;
 480}
 481EXPORT_SYMBOL(printk);
 482
 483/**
 484 * acquire_console_sem - lock the console system for exclusive use.
 485 *
 486 * Acquires a semaphore which guarantees that the caller has
 487 * exclusive access to the console system and the console_drivers list.
 488 *
 489 * Can sleep, returns nothing.
 490 */
 491void acquire_console_sem(void)
 492{
 493        if (in_interrupt())
 494                BUG();
 495        down(&console_sem);
 496        console_may_schedule = 1;
 497}
 498EXPORT_SYMBOL(acquire_console_sem);
 499
 500/**
 501 * release_console_sem - unlock the console system
 502 *
 503 * Releases the semaphore which the caller holds on the console system
 504 * and the console driver list.
 505 *
 506 * While the semaphore was held, console output may have been buffered
 507 * by printk().  If this is the case, release_console_sem() emits
 508 * the output prior to releasing the semaphore.
 509 *
 510 * If there is output waiting for klogd, we wake it up.
 511 *
 512 * release_console_sem() may be called from any context.
 513 */
 514void release_console_sem(void)
 515{
 516        unsigned long flags;
 517        unsigned long _con_start, _log_end;
 518        unsigned long must_wake_klogd = 0;
 519
 520        for ( ; ; ) {
 521                spin_lock_irqsave(&logbuf_lock, flags);
 522                must_wake_klogd |= log_start - log_end;
 523                if (con_start == log_end)
 524                        break;                  /* Nothing to print */
 525                _con_start = con_start;
 526                _log_end = log_end;
 527                con_start = log_end;            /* Flush */
 528                spin_unlock_irqrestore(&logbuf_lock, flags);
 529                call_console_drivers(_con_start, _log_end);
 530        }
 531        console_may_schedule = 0;
 532        up(&console_sem);
 533        spin_unlock_irqrestore(&logbuf_lock, flags);
 534        if (must_wake_klogd && !oops_in_progress)
 535                wake_up_interruptible(&log_wait);
 536}
 537
 538/** console_conditional_schedule - yield the CPU if required
 539 *
 540 * If the console code is currently allowed to sleep, and
 541 * if this CPU should yield the CPU to another task, do
 542 * so here.
 543 *
 544 * Must be called within acquire_console_sem().
 545 */
 546void console_conditional_schedule(void)
 547{
 548        if (console_may_schedule && current->need_resched) {
 549                set_current_state(TASK_RUNNING);
 550                schedule();
 551        }
 552}
 553
 554void console_print(const char *s)
 555{
 556        printk(KERN_EMERG "%s", s);
 557}
 558EXPORT_SYMBOL(console_print);
 559
 560void console_unblank(void)
 561{
 562        struct console *c;
 563
 564        /*
 565         * Try to get the console semaphore. If someone else owns it
 566         * we have to return without unblanking because console_unblank
 567         * may be called in interrupt context.
 568         */
 569        if (down_trylock(&console_sem) != 0)
 570                return;
 571        console_may_schedule = 0;
 572        for (c = console_drivers; c != NULL; c = c->next)
 573                if ((c->flags & CON_ENABLED) && c->unblank)
 574                        c->unblank();
 575        release_console_sem();
 576}
 577EXPORT_SYMBOL(console_unblank);
 578
 579/*
 580 * The console driver calls this routine during kernel initialization
 581 * to register the console printing procedure with printk() and to
 582 * print any messages that were printed by the kernel before the
 583 * console driver was initialized.
 584 */
 585void register_console(struct console * console)
 586{
 587        int     i;
 588        unsigned long flags;
 589
 590        if (preferred_console < 0)
 591                preferred_console = selected_console;
 592
 593        /*
 594         *      See if we want to use this console driver. If we
 595         *      didn't select a console we take the first one
 596         *      that registers here.
 597         */
 598        if (preferred_console < 0) {
 599                if (console->index < 0)
 600                        console->index = 0;
 601                if (console->setup == NULL ||
 602                    console->setup(console, NULL) == 0) {
 603                        console->flags |= CON_ENABLED | CON_CONSDEV;
 604                        preferred_console = 0;
 605                }
 606        }
 607
 608        /*
 609         *      See if this console matches one we selected on
 610         *      the command line.
 611         */
 612        for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) {
 613                if (strcmp(console_cmdline[i].name, console->name) != 0)
 614                        continue;
 615                if (console->index >= 0 &&
 616                    console->index != console_cmdline[i].index)
 617                        continue;
 618                if (console->index < 0)
 619                        console->index = console_cmdline[i].index;
 620                if (console->setup &&
 621                    console->setup(console, console_cmdline[i].options) != 0)
 622                        break;
 623                console->flags |= CON_ENABLED;
 624                console->index = console_cmdline[i].index;
 625                if (i == preferred_console)
 626                        console->flags |= CON_CONSDEV;
 627                break;
 628        }
 629
 630        if (!(console->flags & CON_ENABLED))
 631                return;
 632
 633        /*
 634         *      Put this console in the list - keep the
 635         *      preferred driver at the head of the list.
 636         */
 637        acquire_console_sem();
 638        if ((console->flags & CON_CONSDEV) || console_drivers == NULL) {
 639                console->next = console_drivers;
 640                console_drivers = console;
 641        } else {
 642                console->next = console_drivers->next;
 643                console_drivers->next = console;
 644        }
 645        if (console->flags & CON_PRINTBUFFER) {
 646                /*
 647                 * release_console_sem() will print out the buffered messages for us.
 648                 */
 649                spin_lock_irqsave(&logbuf_lock, flags);
 650                con_start = log_start;
 651                spin_unlock_irqrestore(&logbuf_lock, flags);
 652        }
 653        release_console_sem();
 654}
 655EXPORT_SYMBOL(register_console);
 656
 657int unregister_console(struct console * console)
 658{
 659        struct console *a,*b;
 660        int res = 1;
 661
 662        acquire_console_sem();
 663        if (console_drivers == console) {
 664                console_drivers=console->next;
 665                res = 0;
 666        } else {
 667                for (a=console_drivers->next, b=console_drivers ;
 668                     a; b=a, a=b->next) {
 669                        if (a == console) {
 670                                b->next = a->next;
 671                                res = 0;
 672                                break;
 673                        }  
 674                }
 675        }
 676        
 677        /* If last console is removed, we re-enable picking the first
 678         * one that gets registered. Without that, pmac early boot console
 679         * would prevent fbcon from taking over.
 680         */
 681        if (console_drivers == NULL)
 682                preferred_console = selected_console;
 683                
 684
 685        release_console_sem();
 686        return res;
 687}
 688EXPORT_SYMBOL(unregister_console);
 689        
 690/**
 691 * tty_write_message - write a message to a certain tty, not just the console.
 692 *
 693 * This is used for messages that need to be redirected to a specific tty.
 694 * We don't put it into the syslog queue right now maybe in the future if
 695 * really needed.
 696 */
 697void tty_write_message(struct tty_struct *tty, char *msg)
 698{
 699        if (tty && tty->driver.write)
 700                tty->driver.write(tty, 0, msg, strlen(msg));
 701        return;
 702}
 703
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.