Magellan Linux

Annotation of /alx-src/tags/kernel26-2.6.12-alx-r9/kernel/printk.c

Parent Directory Parent Directory | Revision Log Revision Log


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