print: Allow for more than one output for console messages
This commit is contained in:
parent
a64668b239
commit
5f59e07432
@ -21,7 +21,9 @@
|
||||
#ifndef PRINT_H
|
||||
#define PRINT_H
|
||||
|
||||
void print_init(int (*putc)(char));
|
||||
int print_register_func_early(int (*putc)(char));
|
||||
int print_register_func(int (*putc)(char));
|
||||
int print_unregister_func(int (*putc)(char));
|
||||
int print(char *fmt, ...);
|
||||
int print_func(int (putcf)(char), char *fmt, ...);
|
||||
|
||||
|
@ -18,25 +18,77 @@
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <init.h>
|
||||
#include <list.h>
|
||||
#include <kmalloc.h>
|
||||
#include <print.h>
|
||||
#include <vargs.h>
|
||||
|
||||
/* This function exists solely so crashes don't happen if putc() gets
|
||||
* called before it is initialized. */
|
||||
int putc_initial(char c) {
|
||||
(void)c;
|
||||
struct dlist_node print_funcs_list;
|
||||
|
||||
struct print_func {
|
||||
int (*putc)(char);
|
||||
struct dlist_node list;
|
||||
};
|
||||
|
||||
/*
|
||||
* On startup, we'd like to have print capabilities before kmalloc is
|
||||
* initialized, so statically allocate one struct print_func to allow for the
|
||||
* registration of one print 'sink' before kmalloc is initialized.
|
||||
*/
|
||||
struct print_func print_func_early;
|
||||
int print_register_func_early(int (*putc)(char)) {
|
||||
if (list_empty(&print_funcs_list)) {
|
||||
print_func_early.putc = putc;
|
||||
insert_before(&print_funcs_list, &print_func_early.list);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int print_register_func(int (*putc)(char)) {
|
||||
struct print_func *pf;
|
||||
if (!(pf = kmalloc(sizeof(struct print_func))))
|
||||
return -1;
|
||||
|
||||
pf->putc = putc;
|
||||
insert_before(&print_funcs_list, &pf->list);
|
||||
return 0;
|
||||
}
|
||||
int (*print_putc)(char) = &putc_initial;
|
||||
|
||||
void print_init(int (*putcfn)(char)) {
|
||||
if (putcfn)
|
||||
print_putc = putcfn;
|
||||
int print_unregister_func(int (*putc)(char)) {
|
||||
struct print_func *it;
|
||||
|
||||
if (list_empty(&print_funcs_list))
|
||||
return -1;
|
||||
|
||||
for_each_list(it, &print_funcs_list, struct print_func, list) {
|
||||
if (it->putc == putc) {
|
||||
remove(&it->list);
|
||||
|
||||
//only kfree if it was kmalloced
|
||||
if (it != &print_func_early)
|
||||
kfree(it);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int print_putc(char c) {
|
||||
struct print_func *it;
|
||||
|
||||
if (list_empty(&print_funcs_list))
|
||||
return -1;
|
||||
|
||||
for_each_list(it, &print_funcs_list, struct print_func, list)
|
||||
it->putc(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void puts(int (*putc)(char), const char *s)
|
||||
{
|
||||
while (*s) putc (*s++);
|
||||
while (*s) putc(*s++);
|
||||
}
|
||||
|
||||
void puti(int (*putc)(char), int i)
|
||||
@ -132,7 +184,7 @@ int print(char *fmt, ...) {
|
||||
va_list arg;
|
||||
|
||||
va_start(arg, fmt);
|
||||
ret = _print(print_putc, fmt, arg);
|
||||
ret = _print(&print_putc, fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
return ret;
|
||||
@ -149,3 +201,9 @@ int print_func(int (*putc)(char), char *fmt, ...) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void print_init() {
|
||||
init_list(&print_funcs_list);
|
||||
}
|
||||
|
||||
early_initcall(print_init);
|
||||
|
@ -59,6 +59,7 @@ void video_console_init(void) {
|
||||
if ((console_init(&console_fb)))
|
||||
return;
|
||||
|
||||
print_register_func(&console_putc);
|
||||
print_console_logo();
|
||||
|
||||
print_func(&console_putc, "Successfully initialized video console on %s.\n", fbdev->name);
|
||||
@ -70,7 +71,7 @@ void serial_console_init() {
|
||||
if (!sdev)
|
||||
return;
|
||||
|
||||
print_init(sdev->putc);
|
||||
print_register_func_early(sdev->putc);
|
||||
print("Successfully initialized serial console on %s\n", sdev->name);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user