Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.30-rc6 170 lines 3.7 kB view raw
1/* 2 * Based on the same principle as kgdboe using the NETPOLL api, this 3 * driver uses a console polling api to implement a gdb serial inteface 4 * which is multiplexed on a console port. 5 * 6 * Maintainer: Jason Wessel <jason.wessel@windriver.com> 7 * 8 * 2007-2008 (c) Jason Wessel - Wind River Systems, Inc. 9 * 10 * This file is licensed under the terms of the GNU General Public 11 * License version 2. This program is licensed "as is" without any 12 * warranty of any kind, whether express or implied. 13 */ 14#include <linux/kernel.h> 15#include <linux/ctype.h> 16#include <linux/kgdb.h> 17#include <linux/tty.h> 18 19#define MAX_CONFIG_LEN 40 20 21static struct kgdb_io kgdboc_io_ops; 22 23/* -1 = init not run yet, 0 = unconfigured, 1 = configured. */ 24static int configured = -1; 25 26static char config[MAX_CONFIG_LEN]; 27static struct kparam_string kps = { 28 .string = config, 29 .maxlen = MAX_CONFIG_LEN, 30}; 31 32static struct tty_driver *kgdb_tty_driver; 33static int kgdb_tty_line; 34 35static int kgdboc_option_setup(char *opt) 36{ 37 if (strlen(opt) > MAX_CONFIG_LEN) { 38 printk(KERN_ERR "kgdboc: config string too long\n"); 39 return -ENOSPC; 40 } 41 strcpy(config, opt); 42 43 return 0; 44} 45 46__setup("kgdboc=", kgdboc_option_setup); 47 48static int configure_kgdboc(void) 49{ 50 struct tty_driver *p; 51 int tty_line = 0; 52 int err; 53 54 err = kgdboc_option_setup(config); 55 if (err || !strlen(config) || isspace(config[0])) 56 goto noconfig; 57 58 err = -ENODEV; 59 60 p = tty_find_polling_driver(config, &tty_line); 61 if (!p) 62 goto noconfig; 63 64 kgdb_tty_driver = p; 65 kgdb_tty_line = tty_line; 66 67 err = kgdb_register_io_module(&kgdboc_io_ops); 68 if (err) 69 goto noconfig; 70 71 configured = 1; 72 73 return 0; 74 75noconfig: 76 config[0] = 0; 77 configured = 0; 78 79 return err; 80} 81 82static int __init init_kgdboc(void) 83{ 84 /* Already configured? */ 85 if (configured == 1) 86 return 0; 87 88 return configure_kgdboc(); 89} 90 91static void cleanup_kgdboc(void) 92{ 93 if (configured == 1) 94 kgdb_unregister_io_module(&kgdboc_io_ops); 95} 96 97static int kgdboc_get_char(void) 98{ 99 return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver, 100 kgdb_tty_line); 101} 102 103static void kgdboc_put_char(u8 chr) 104{ 105 kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver, 106 kgdb_tty_line, chr); 107} 108 109static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp) 110{ 111 int len = strlen(kmessage); 112 113 if (len >= MAX_CONFIG_LEN) { 114 printk(KERN_ERR "kgdboc: config string too long\n"); 115 return -ENOSPC; 116 } 117 118 /* Only copy in the string if the init function has not run yet */ 119 if (configured < 0) { 120 strcpy(config, kmessage); 121 return 0; 122 } 123 124 if (kgdb_connected) { 125 printk(KERN_ERR 126 "kgdboc: Cannot reconfigure while KGDB is connected.\n"); 127 128 return -EBUSY; 129 } 130 131 strcpy(config, kmessage); 132 /* Chop out \n char as a result of echo */ 133 if (config[len - 1] == '\n') 134 config[len - 1] = '\0'; 135 136 if (configured == 1) 137 cleanup_kgdboc(); 138 139 /* Go and configure with the new params. */ 140 return configure_kgdboc(); 141} 142 143static void kgdboc_pre_exp_handler(void) 144{ 145 /* Increment the module count when the debugger is active */ 146 if (!kgdb_connected) 147 try_module_get(THIS_MODULE); 148} 149 150static void kgdboc_post_exp_handler(void) 151{ 152 /* decrement the module count when the debugger detaches */ 153 if (!kgdb_connected) 154 module_put(THIS_MODULE); 155} 156 157static struct kgdb_io kgdboc_io_ops = { 158 .name = "kgdboc", 159 .read_char = kgdboc_get_char, 160 .write_char = kgdboc_put_char, 161 .pre_exception = kgdboc_pre_exp_handler, 162 .post_exception = kgdboc_post_exp_handler, 163}; 164 165module_init(init_kgdboc); 166module_exit(cleanup_kgdboc); 167module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644); 168MODULE_PARM_DESC(kgdboc, "<serial_device>[,baud]"); 169MODULE_DESCRIPTION("KGDB Console TTY Driver"); 170MODULE_LICENSE("GPL");