@ -51,6 +51,9 @@
# define CREATE_TRACE_POINTS
# include <trace/events/printk.h>
# include "console_cmdline.h"
# include "braille.h"
/* printk's without a loglevel use this.. */
# define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL
@ -105,19 +108,11 @@ static struct console *exclusive_console;
/*
* Array of consoles built from command line options ( console = )
*/
struct console_cmdline
{
char name [ 8 ] ; /* Name of the driver */
int index ; /* Minor dev. to use */
char * options ; /* Options for the driver */
# ifdef CONFIG_A11Y_BRAILLE_CONSOLE
char * brl_options ; /* Options for braille driver */
# endif
} ;
# define MAX_CMDLINECONSOLES 8
static struct console_cmdline console_cmdline [ MAX_CMDLINECONSOLES ] ;
static int selected_console = - 1 ;
static int preferred_console = - 1 ;
int console_set_on_cmdline ;
@ -178,7 +173,7 @@ static int console_may_schedule;
* 67 " g "
* 0032 00 00 00 padding to next message header
*
* The ' struct log ' buffer header must never be directly exported to
* The ' struct printk_ log' buffer header must never be directly exported to
* userspace , it is a kernel - private implementation detail that might
* need to be changed in the future , when the requirements change .
*
@ -200,7 +195,7 @@ enum log_flags {
LOG_CONT = 8 , /* text is a fragment of a continuation line */
} ;
struct log {
struct printk_ log {
u64 ts_nsec ; /* timestamp in nanoseconds */
u16 len ; /* length of entire record */
u16 text_len ; /* length of text buffer */
@ -248,7 +243,7 @@ static u32 clear_idx;
# if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
# define LOG_ALIGN 4
# else
# define LOG_ALIGN __alignof__(struct log)
# define LOG_ALIGN __alignof__(struct printk_ log)
# endif
# define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
static char __log_buf [ __LOG_BUF_LEN ] __aligned ( LOG_ALIGN ) ;
@ -259,35 +254,35 @@ static u32 log_buf_len = __LOG_BUF_LEN;
static volatile unsigned int logbuf_cpu = UINT_MAX ;
/* human readable text of the record */
static char * log_text ( const struct log * msg )
static char * log_text ( const struct printk_ log * msg )
{
return ( char * ) msg + sizeof ( struct log ) ;
return ( char * ) msg + sizeof ( struct printk_ log) ;
}
/* optional key/value pair dictionary attached to the record */
static char * log_dict ( const struct log * msg )
static char * log_dict ( const struct printk_ log * msg )
{
return ( char * ) msg + sizeof ( struct log ) + msg - > text_len ;
return ( char * ) msg + sizeof ( struct printk_ log) + msg - > text_len ;
}
/* get record by index; idx must point to valid msg */
static struct log * log_from_idx ( u32 idx )
static struct printk_ log * log_from_idx ( u32 idx )
{
struct log * msg = ( struct log * ) ( log_buf + idx ) ;
struct printk_ log * msg = ( struct printk_ log * ) ( log_buf + idx ) ;
/*
* A length = = 0 record is the end of buffer marker . Wrap around and
* read the message at the start of the buffer .
*/
if ( ! msg - > len )
return ( struct log * ) log_buf ;
return ( struct printk_ log * ) log_buf ;
return msg ;
}
/* get next record; idx must point to valid msg */
static u32 log_next ( u32 idx )
{
struct log * msg = ( struct log * ) ( log_buf + idx ) ;
struct printk_ log * msg = ( struct printk_ log * ) ( log_buf + idx ) ;
/* length == 0 indicates the end of the buffer; wrap */
/*
@ -296,7 +291,7 @@ static u32 log_next(u32 idx)
* return the one after that .
*/
if ( ! msg - > len ) {
msg = ( struct log * ) log_buf ;
msg = ( struct printk_ log * ) log_buf ;
return msg - > len ;
}
return idx + msg - > len ;
@ -308,11 +303,11 @@ static void log_store(int facility, int level,
const char * dict , u16 dict_len ,
const char * text , u16 text_len )
{
struct log * msg ;
struct printk_ log * msg ;
u32 size , pad_len ;
/* number of '\0' padding bytes to next message */
size = sizeof ( struct log ) + text_len + dict_len ;
size = sizeof ( struct printk_ log) + text_len + dict_len ;
pad_len = ( - size ) & ( LOG_ALIGN - 1 ) ;
size + = pad_len ;
@ -324,7 +319,7 @@ static void log_store(int facility, int level,
else
free = log_first_idx - log_next_idx ;
if ( free > size + sizeof ( struct log ) )
if ( free > size + sizeof ( struct printk_ log) )
break ;
/* drop old messages until we have enough contiuous space */
@ -332,18 +327,18 @@ static void log_store(int facility, int level,
log_first_seq + + ;
}
if ( log_next_idx + size + sizeof ( struct log ) > = log_buf_len ) {
if ( log_next_idx + size + sizeof ( struct printk_ log) > = log_buf_len ) {
/*
* This message + an additional empty header does not fit
* at the end of the buffer . Add an empty header with len = = 0
* to signify a wrap around .
*/
memset ( log_buf + log_next_idx , 0 , sizeof ( struct log ) ) ;
memset ( log_buf + log_next_idx , 0 , sizeof ( struct printk_ log) ) ;
log_next_idx = 0 ;
}
/* fill message */
msg = ( struct log * ) ( log_buf + log_next_idx ) ;
msg = ( struct printk_ log * ) ( log_buf + log_next_idx ) ;
memcpy ( log_text ( msg ) , text , text_len ) ;
msg - > text_len = text_len ;
memcpy ( log_dict ( msg ) , dict , dict_len ) ;
@ -356,7 +351,7 @@ static void log_store(int facility, int level,
else
msg - > ts_nsec = local_clock ( ) ;
memset ( log_dict ( msg ) + dict_len , 0 , pad_len ) ;
msg - > len = sizeof ( struct log ) + text_len + dict_len + pad_len ;
msg - > len = sizeof ( struct printk_ log) + text_len + dict_len + pad_len ;
/* insert message */
log_next_idx + = msg - > len ;
@ -479,7 +474,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
size_t count , loff_t * ppos )
{
struct devkmsg_user * user = file - > private_data ;
struct log * msg ;
struct printk_ log * msg ;
u64 ts_usec ;
size_t i ;
char cont = ' - ' ;
@ -724,14 +719,14 @@ void log_buf_kexec_setup(void)
VMCOREINFO_SYMBOL ( log_first_idx ) ;
VMCOREINFO_SYMBOL ( log_next_idx ) ;
/*
* Export struct log size and field offsets . User space tools can
* Export struct printk_ log size and field offsets . User space tools can
* parse it and detect any changes to structure down the line .
*/
VMCOREINFO_STRUCT_SIZE ( log ) ;
VMCOREINFO_OFFSET ( log , ts_nsec ) ;
VMCOREINFO_OFFSET ( log , len ) ;
VMCOREINFO_OFFSET ( log , text_len ) ;
VMCOREINFO_OFFSET ( log , dict_len ) ;
VMCOREINFO_STRUCT_SIZE ( printk_ log) ;
VMCOREINFO_OFFSET ( printk_ log, ts_nsec ) ;
VMCOREINFO_OFFSET ( printk_ log, len ) ;
VMCOREINFO_OFFSET ( printk_ log, text_len ) ;
VMCOREINFO_OFFSET ( printk_ log, dict_len ) ;
}
# endif
@ -884,7 +879,7 @@ static size_t print_time(u64 ts, char *buf)
( unsigned long ) ts , rem_nsec / 1000 ) ;
}
static size_t print_prefix ( const struct log * msg , bool syslog , char * buf )
static size_t print_prefix ( const struct printk_ log * msg , bool syslog , char * buf )
{
size_t len = 0 ;
unsigned int prefix = ( msg - > facility < < 3 ) | msg - > level ;
@ -907,7 +902,7 @@ static size_t print_prefix(const struct log *msg, bool syslog, char *buf)
return len ;
}
static size_t msg_print_text ( const struct log * msg , enum log_flags prev ,
static size_t msg_print_text ( const struct printk_ log * msg , enum log_flags prev ,
bool syslog , char * buf , size_t size )
{
const char * text = log_text ( msg ) ;
@ -969,7 +964,7 @@ static size_t msg_print_text(const struct log *msg, enum log_flags prev,
static int syslog_print ( char __user * buf , int size )
{
char * text ;
struct log * msg ;
struct printk_ log * msg ;
int len = 0 ;
text = kmalloc ( LOG_LINE_MAX + PREFIX_MAX , GFP_KERNEL ) ;
@ -1060,7 +1055,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
idx = clear_idx ;
prev = 0 ;
while ( seq < log_next_seq ) {
struct log * msg = log_from_idx ( idx ) ;
struct printk_ log * msg = log_from_idx ( idx ) ;
len + = msg_print_text ( msg , prev , true , NULL , 0 ) ;
prev = msg - > flags ;
@ -1073,7 +1068,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
idx = clear_idx ;
prev = 0 ;
while ( len > size & & seq < log_next_seq ) {
struct log * msg = log_from_idx ( idx ) ;
struct printk_ log * msg = log_from_idx ( idx ) ;
len - = msg_print_text ( msg , prev , true , NULL , 0 ) ;
prev = msg - > flags ;
@ -1087,7 +1082,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
len = 0 ;
prev = 0 ;
while ( len > = 0 & & seq < next_seq ) {
struct log * msg = log_from_idx ( idx ) ;
struct printk_ log * msg = log_from_idx ( idx ) ;
int textlen ;
textlen = msg_print_text ( msg , prev , true , text ,
@ -1233,7 +1228,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
error = 0 ;
while ( seq < log_next_seq ) {
struct log * msg = log_from_idx ( idx ) ;
struct printk_ log * msg = log_from_idx ( idx ) ;
error + = msg_print_text ( msg , prev , true , NULL , 0 ) ;
idx = log_next ( idx ) ;
@ -1719,10 +1714,10 @@ static struct cont {
u8 level ;
bool flushed : 1 ;
} cont ;
static struct log * log_from_idx ( u32 idx ) { return NULL ; }
static struct printk_ log * log_from_idx ( u32 idx ) { return NULL ; }
static u32 log_next ( u32 idx ) { return 0 ; }
static void call_console_drivers ( int level , const char * text , size_t len ) { }
static size_t msg_print_text ( const struct log * msg , enum log_flags prev ,
static size_t msg_print_text ( const struct printk_ log * msg , enum log_flags prev ,
bool syslog , char * buf , size_t size ) { return 0 ; }
static size_t cont_print_text ( char * text , size_t size ) { return 0 ; }
@ -1761,23 +1756,23 @@ static int __add_preferred_console(char *name, int idx, char *options,
* See if this tty is not yet registered , and
* if we have a slot free .
*/
for ( i = 0 ; i < MAX_CMDLINECONSOLES & & console_cmdline [ i ] . name [ 0 ] ; i + + )
if ( strcmp ( console_cmdline [ i ] . name , name ) = = 0 & &
console_cmdline [ i ] . index = = idx ) {
if ( ! brl_options )
selected_console = i ;
return 0 ;
for ( i = 0 , c = console_cmdline ;
i < MAX_CMDLINECONSOLES & & c - > name [ 0 ] ;
i + + , c + + ) {
if ( strcmp ( c - > name , name ) = = 0 & & c - > index = = idx ) {
if ( ! brl_options )
selected_console = i ;
return 0 ;
}
}
if ( i = = MAX_CMDLINECONSOLES )
return - E2BIG ;
if ( ! brl_options )
selected_console = i ;
c = & console_cmdline [ i ] ;
strlcpy ( c - > name , name , sizeof ( c - > name ) ) ;
c - > options = options ;
# ifdef CONFIG_A11Y_BRAILLE_CONSOLE
c - > brl_options = brl_options ;
# endif
braille_set_options ( c , brl_options ) ;
c - > index = idx ;
return 0 ;
}
@ -1790,20 +1785,8 @@ static int __init console_setup(char *str)
char * s , * options , * brl_options = NULL ;
int idx ;
# ifdef CONFIG_A11Y_BRAILLE_CONSOLE
if ( ! memcmp ( str , " brl, " , 4 ) ) {
brl_options = " " ;
str + = 4 ;
} else if ( ! memcmp ( str , " brl= " , 4 ) ) {
brl_options = str + 4 ;
str = strchr ( brl_options , ' , ' ) ;
if ( ! str ) {
printk ( KERN_ERR " need port name after brl= \n " ) ;
return 1 ;
}
* ( str + + ) = 0 ;
}
# endif
if ( _braille_console_setup ( & str , & brl_options ) )
return 1 ;
/*
* Decode str into name , index , options .
@ -1858,15 +1841,15 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha
struct console_cmdline * c ;
int i ;
for ( i = 0 ; i < MAX_CMDLINECONSOLES & & console_cmdline [ i ] . name [ 0 ] ; i + + )
if ( strcmp ( console_cmdline [ i ] . name , name ) = = 0 & &
console_cmdline [ i ] . index = = idx ) {
c = & console_cmdline [ i ] ;
strlcpy ( c - > name , name_new , sizeof ( c - > name ) ) ;
c - > name [ sizeof ( c - > name ) - 1 ] = 0 ;
c - > options = options ;
c - > index = idx_new ;
return i ;
for ( i = 0 , c = console_cmdline ;
i < MAX_CMDLINECONSOLES & & c - > name [ 0 ] ;
i + + , c + + )
if ( strcmp ( c - > name , name ) = = 0 & & c - > index = = idx ) {
strlcpy ( c - > name , name_new , sizeof ( c - > name ) ) ;
c - > name [ sizeof ( c - > name ) - 1 ] = 0 ;
c - > options = options ;
c - > index = idx_new ;
return i ;
}
/* not found */
return - 1 ;
@ -2046,7 +2029,7 @@ void console_unlock(void)
console_cont_flush ( text , sizeof ( text ) ) ;
again :
for ( ; ; ) {
struct log * msg ;
struct printk_ log * msg ;
size_t len ;
int level ;
@ -2241,6 +2224,7 @@ void register_console(struct console *newcon)
int i ;
unsigned long flags ;
struct console * bcon = NULL ;
struct console_cmdline * c ;
/*
* before we register a new CON_BOOT console , make sure we don ' t
@ -2288,30 +2272,25 @@ void register_console(struct console *newcon)
* See if this console matches one we selected on
* the command line .
*/
for ( i = 0 ; i < MAX_CMDLINECONSOLES & & console_cmdline [ i ] . name [ 0 ] ;
i + + ) {
if ( strcmp ( console_cmdline [ i ] . name , newcon - > name ) ! = 0 )
for ( i = 0 , c = console_cmdline ;
i < MAX_CMDLINECONSOLES & & c - > name [ 0 ] ;
i + + , c + + ) {
if ( strcmp ( c - > name , newcon - > name ) ! = 0 )
continue ;
if ( newcon - > index > = 0 & &
newcon - > index ! = console_cmdline [ i ] . index )
newcon - > index ! = c - > index )
continue ;
if ( newcon - > index < 0 )
newcon - > index = console_cmdline [ i ] . index ;
# ifdef CONFIG_A11Y_BRAILLE_CONSOLE
if ( console_cmdline [ i ] . brl_options ) {
newcon - > flags | = CON_BRL ;
braille_register_console ( newcon ,
console_cmdline [ i ] . index ,
console_cmdline [ i ] . options ,
console_cmdline [ i ] . brl_options ) ;
newcon - > index = c - > index ;
if ( _braille_register_console ( newcon , c ) )
return ;
}
# endif
if ( newcon - > setup & &
newcon - > setup ( newcon , console_cmdline [ i ] . options ) ! = 0 )
break ;
newcon - > flags | = CON_ENABLED ;
newcon - > index = console_cmdline [ i ] . index ;
newcon - > index = c - > index ;
if ( i = = selected_console ) {
newcon - > flags | = CON_CONSDEV ;
preferred_console = selected_console ;
@ -2394,13 +2373,13 @@ EXPORT_SYMBOL(register_console);
int unregister_console ( struct console * console )
{
struct console * a , * b ;
int res = 1 ;
int res ;
# ifdef CONFIG_A11Y_BRAILLE_CONSOLE
if ( console - > flags & CON_BRL )
return braille_unregister_console ( console ) ;
# endif
res = _braille_unregister_console ( console ) ;
if ( res )
return res ;
res = 1 ;
console_lock ( ) ;
if ( console_drivers = = console ) {
console_drivers = console - > next ;
@ -2666,7 +2645,7 @@ void kmsg_dump(enum kmsg_dump_reason reason)
bool kmsg_dump_get_line_nolock ( struct kmsg_dumper * dumper , bool syslog ,
char * line , size_t size , size_t * len )
{
struct log * msg ;
struct printk_ log * msg ;
size_t l = 0 ;
bool ret = false ;
@ -2778,7 +2757,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
idx = dumper - > cur_idx ;
prev = 0 ;
while ( seq < dumper - > next_seq ) {
struct log * msg = log_from_idx ( idx ) ;
struct printk_ log * msg = log_from_idx ( idx ) ;
l + = msg_print_text ( msg , prev , true , NULL , 0 ) ;
idx = log_next ( idx ) ;
@ -2791,7 +2770,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
idx = dumper - > cur_idx ;
prev = 0 ;
while ( l > size & & seq < dumper - > next_seq ) {
struct log * msg = log_from_idx ( idx ) ;
struct printk_ log * msg = log_from_idx ( idx ) ;
l - = msg_print_text ( msg , prev , true , NULL , 0 ) ;
idx = log_next ( idx ) ;
@ -2806,7 +2785,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
l = 0 ;
prev = 0 ;
while ( seq < dumper - > next_seq ) {
struct log * msg = log_from_idx ( idx ) ;
struct printk_ log * msg = log_from_idx ( idx ) ;
l + = msg_print_text ( msg , prev , syslog , buf + l , size - l ) ;
idx = log_next ( idx ) ;