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
|
#ifndef PRINT_H
|
||||||
#define 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(char *fmt, ...);
|
||||||
int print_func(int (putcf)(char), char *fmt, ...);
|
int print_func(int (putcf)(char), char *fmt, ...);
|
||||||
|
|
||||||
|
@ -18,25 +18,77 @@
|
|||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <init.h>
|
||||||
|
#include <list.h>
|
||||||
|
#include <kmalloc.h>
|
||||||
#include <print.h>
|
#include <print.h>
|
||||||
#include <vargs.h>
|
#include <vargs.h>
|
||||||
|
|
||||||
/* This function exists solely so crashes don't happen if putc() gets
|
struct dlist_node print_funcs_list;
|
||||||
* called before it is initialized. */
|
|
||||||
int putc_initial(char c) {
|
struct print_func {
|
||||||
(void)c;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
int (*print_putc)(char) = &putc_initial;
|
|
||||||
|
|
||||||
void print_init(int (*putcfn)(char)) {
|
int print_unregister_func(int (*putc)(char)) {
|
||||||
if (putcfn)
|
struct print_func *it;
|
||||||
print_putc = putcfn;
|
|
||||||
|
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)
|
void puts(int (*putc)(char), const char *s)
|
||||||
{
|
{
|
||||||
while (*s) putc (*s++);
|
while (*s) putc(*s++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void puti(int (*putc)(char), int i)
|
void puti(int (*putc)(char), int i)
|
||||||
@ -132,7 +184,7 @@ int print(char *fmt, ...) {
|
|||||||
va_list arg;
|
va_list arg;
|
||||||
|
|
||||||
va_start(arg, fmt);
|
va_start(arg, fmt);
|
||||||
ret = _print(print_putc, fmt, arg);
|
ret = _print(&print_putc, fmt, arg);
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -149,3 +201,9 @@ int print_func(int (*putc)(char), char *fmt, ...) {
|
|||||||
|
|
||||||
return ret;
|
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)))
|
if ((console_init(&console_fb)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
print_register_func(&console_putc);
|
||||||
print_console_logo();
|
print_console_logo();
|
||||||
|
|
||||||
print_func(&console_putc, "Successfully initialized video console on %s.\n", fbdev->name);
|
print_func(&console_putc, "Successfully initialized video console on %s.\n", fbdev->name);
|
||||||
@ -70,7 +71,7 @@ void serial_console_init() {
|
|||||||
if (!sdev)
|
if (!sdev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
print_init(sdev->putc);
|
print_register_func_early(sdev->putc);
|
||||||
print("Successfully initialized serial console on %s\n", sdev->name);
|
print("Successfully initialized serial console on %s\n", sdev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user