11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/drivers/net/netconsole.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 2001 Ingo Molnar <mingo@redhat.com> 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * This file contains the implementation of an IRQ-safe, crash-safe 71da177e4SLinus Torvalds * kernel console implementation that outputs kernel messages to the 81da177e4SLinus Torvalds * network. 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * Modification history: 111da177e4SLinus Torvalds * 121da177e4SLinus Torvalds * 2001-09-17 started by Ingo Molnar. 131da177e4SLinus Torvalds * 2003-08-11 2.6 port by Matt Mackall 141da177e4SLinus Torvalds * simplified options 151da177e4SLinus Torvalds * generic card hooks 161da177e4SLinus Torvalds * works non-modular 171da177e4SLinus Torvalds * 2003-09-07 rewritten with netpoll api 181da177e4SLinus Torvalds */ 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds /**************************************************************** 211da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 221da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 231da177e4SLinus Torvalds * the Free Software Foundation; either version 2, or (at your option) 241da177e4SLinus Torvalds * any later version. 251da177e4SLinus Torvalds * 261da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful, 271da177e4SLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 281da177e4SLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 291da177e4SLinus Torvalds * GNU General Public License for more details. 301da177e4SLinus Torvalds * 311da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 321da177e4SLinus Torvalds * along with this program; if not, write to the Free Software 331da177e4SLinus Torvalds * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 341da177e4SLinus Torvalds * 351da177e4SLinus Torvalds ****************************************************************/ 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds #include <linux/mm.h> 381da177e4SLinus Torvalds #include <linux/tty.h> 391da177e4SLinus Torvalds #include <linux/init.h> 401da177e4SLinus Torvalds #include <linux/module.h> 411da177e4SLinus Torvalds #include <linux/console.h> 421da177e4SLinus Torvalds #include <linux/tty_driver.h> 431da177e4SLinus Torvalds #include <linux/moduleparam.h> 441da177e4SLinus Torvalds #include <linux/string.h> 451da177e4SLinus Torvalds #include <linux/sysrq.h> 461da177e4SLinus Torvalds #include <linux/smp.h> 471da177e4SLinus Torvalds #include <linux/netpoll.h> 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds MODULE_AUTHOR("Maintainer: Matt Mackall <mpm@selenic.com>"); 501da177e4SLinus Torvalds MODULE_DESCRIPTION("Console driver for network interfaces"); 511da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 521da177e4SLinus Torvalds 531da177e4SLinus Torvalds static char config[256]; 541da177e4SLinus Torvalds module_param_string(netconsole, config, 256, 0); 551da177e4SLinus Torvalds MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n"); 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds static struct netpoll np = { 581da177e4SLinus Torvalds .name = "netconsole", 591da177e4SLinus Torvalds .dev_name = "eth0", 601da177e4SLinus Torvalds .local_port = 6665, 611da177e4SLinus Torvalds .remote_port = 6666, 621da177e4SLinus Torvalds .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 631da177e4SLinus Torvalds .drop = netpoll_queue, 641da177e4SLinus Torvalds }; 651da177e4SLinus Torvalds static int configured = 0; 661da177e4SLinus Torvalds 671da177e4SLinus Torvalds #define MAX_PRINT_CHUNK 1000 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds static void write_msg(struct console *con, const char *msg, unsigned int len) 701da177e4SLinus Torvalds { 711da177e4SLinus Torvalds int frag, left; 721da177e4SLinus Torvalds unsigned long flags; 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds if (!np.dev) 751da177e4SLinus Torvalds return; 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds local_irq_save(flags); 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds for(left = len; left; ) { 801da177e4SLinus Torvalds frag = min(left, MAX_PRINT_CHUNK); 811da177e4SLinus Torvalds netpoll_send_udp(&np, msg, frag); 821da177e4SLinus Torvalds msg += frag; 831da177e4SLinus Torvalds left -= frag; 841da177e4SLinus Torvalds } 851da177e4SLinus Torvalds 861da177e4SLinus Torvalds local_irq_restore(flags); 871da177e4SLinus Torvalds } 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds static struct console netconsole = { 90d938ab44SRandy Dunlap .name = "netcon", 911da177e4SLinus Torvalds .flags = CON_ENABLED | CON_PRINTBUFFER, 921da177e4SLinus Torvalds .write = write_msg 931da177e4SLinus Torvalds }; 941da177e4SLinus Torvalds 951da177e4SLinus Torvalds static int option_setup(char *opt) 961da177e4SLinus Torvalds { 971da177e4SLinus Torvalds configured = !netpoll_parse_options(&np, opt); 989b41046cSOGAWA Hirofumi return 1; 991da177e4SLinus Torvalds } 1001da177e4SLinus Torvalds 1011da177e4SLinus Torvalds __setup("netconsole=", option_setup); 1021da177e4SLinus Torvalds 1031da177e4SLinus Torvalds static int init_netconsole(void) 1041da177e4SLinus Torvalds { 1051da177e4SLinus Torvalds if(strlen(config)) 1061da177e4SLinus Torvalds option_setup(config); 1071da177e4SLinus Torvalds 1081da177e4SLinus Torvalds if(!configured) { 1091da177e4SLinus Torvalds printk("netconsole: not configured, aborting\n"); 1101da177e4SLinus Torvalds return -EINVAL; 1111da177e4SLinus Torvalds } 1121da177e4SLinus Torvalds 1131da177e4SLinus Torvalds if(netpoll_setup(&np)) 1141da177e4SLinus Torvalds return -EINVAL; 1151da177e4SLinus Torvalds 1161da177e4SLinus Torvalds register_console(&netconsole); 1171da177e4SLinus Torvalds printk(KERN_INFO "netconsole: network logging started\n"); 1181da177e4SLinus Torvalds return 0; 1191da177e4SLinus Torvalds } 1201da177e4SLinus Torvalds 1211da177e4SLinus Torvalds static void cleanup_netconsole(void) 1221da177e4SLinus Torvalds { 1231da177e4SLinus Torvalds unregister_console(&netconsole); 1241da177e4SLinus Torvalds netpoll_cleanup(&np); 1251da177e4SLinus Torvalds } 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds module_init(init_netconsole); 1281da177e4SLinus Torvalds module_exit(cleanup_netconsole); 129