Linux Audio

Check our new training course

Loading...
v3.1
  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/kdb.h>
 18#include <linux/tty.h>
 19#include <linux/console.h>
 20#include <linux/vt_kern.h>
 21#include <linux/input.h>
 
 22
 23#define MAX_CONFIG_LEN		40
 24
 25static struct kgdb_io		kgdboc_io_ops;
 26
 27/* -1 = init not run yet, 0 = unconfigured, 1 = configured. */
 28static int configured		= -1;
 29
 30static char config[MAX_CONFIG_LEN];
 31static struct kparam_string kps = {
 32	.string			= config,
 33	.maxlen			= MAX_CONFIG_LEN,
 34};
 35
 36static int kgdboc_use_kms;  /* 1 if we use kernel mode switching */
 37static struct tty_driver	*kgdb_tty_driver;
 38static int			kgdb_tty_line;
 39
 40#ifdef CONFIG_KDB_KEYBOARD
 41static int kgdboc_reset_connect(struct input_handler *handler,
 42				struct input_dev *dev,
 43				const struct input_device_id *id)
 44{
 45	input_reset_device(dev);
 46
 47	/* Retrun an error - we do not want to bind, just to reset */
 48	return -ENODEV;
 49}
 50
 51static void kgdboc_reset_disconnect(struct input_handle *handle)
 52{
 53	/* We do not expect anyone to actually bind to us */
 54	BUG();
 55}
 56
 57static const struct input_device_id kgdboc_reset_ids[] = {
 58	{
 59		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
 60		.evbit = { BIT_MASK(EV_KEY) },
 61	},
 62	{ }
 63};
 64
 65static struct input_handler kgdboc_reset_handler = {
 66	.connect	= kgdboc_reset_connect,
 67	.disconnect	= kgdboc_reset_disconnect,
 68	.name		= "kgdboc_reset",
 69	.id_table	= kgdboc_reset_ids,
 70};
 71
 72static DEFINE_MUTEX(kgdboc_reset_mutex);
 73
 74static void kgdboc_restore_input_helper(struct work_struct *dummy)
 75{
 76	/*
 77	 * We need to take a mutex to prevent several instances of
 78	 * this work running on different CPUs so they don't try
 79	 * to register again already registered handler.
 80	 */
 81	mutex_lock(&kgdboc_reset_mutex);
 82
 83	if (input_register_handler(&kgdboc_reset_handler) == 0)
 84		input_unregister_handler(&kgdboc_reset_handler);
 85
 86	mutex_unlock(&kgdboc_reset_mutex);
 87}
 88
 89static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
 90
 91static void kgdboc_restore_input(void)
 92{
 93	if (likely(system_state == SYSTEM_RUNNING))
 94		schedule_work(&kgdboc_restore_input_work);
 95}
 96
 97static int kgdboc_register_kbd(char **cptr)
 98{
 99	if (strncmp(*cptr, "kbd", 3) == 0) {
 
100		if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
101			kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
102			kdb_poll_idx++;
103			if (cptr[0][3] == ',')
104				*cptr += 4;
105			else
106				return 1;
107		}
108	}
109	return 0;
110}
111
112static void kgdboc_unregister_kbd(void)
113{
114	int i;
115
116	for (i = 0; i < kdb_poll_idx; i++) {
117		if (kdb_poll_funcs[i] == kdb_get_kbd_char) {
118			kdb_poll_idx--;
119			kdb_poll_funcs[i] = kdb_poll_funcs[kdb_poll_idx];
120			kdb_poll_funcs[kdb_poll_idx] = NULL;
121			i--;
122		}
123	}
124	flush_work_sync(&kgdboc_restore_input_work);
125}
126#else /* ! CONFIG_KDB_KEYBOARD */
127#define kgdboc_register_kbd(x) 0
128#define kgdboc_unregister_kbd()
129#define kgdboc_restore_input()
130#endif /* ! CONFIG_KDB_KEYBOARD */
131
132static int kgdboc_option_setup(char *opt)
133{
134	if (strlen(opt) >= MAX_CONFIG_LEN) {
135		printk(KERN_ERR "kgdboc: config string too long\n");
136		return -ENOSPC;
137	}
138	strcpy(config, opt);
139
140	return 0;
141}
142
143__setup("kgdboc=", kgdboc_option_setup);
144
145static void cleanup_kgdboc(void)
146{
 
 
147	kgdboc_unregister_kbd();
148	if (configured == 1)
149		kgdb_unregister_io_module(&kgdboc_io_ops);
150}
151
152static int configure_kgdboc(void)
153{
154	struct tty_driver *p;
155	int tty_line = 0;
156	int err;
157	char *cptr = config;
158	struct console *cons;
159
160	err = kgdboc_option_setup(config);
161	if (err || !strlen(config) || isspace(config[0]))
162		goto noconfig;
163
164	err = -ENODEV;
165	kgdboc_io_ops.is_console = 0;
166	kgdb_tty_driver = NULL;
167
168	kgdboc_use_kms = 0;
169	if (strncmp(cptr, "kms,", 4) == 0) {
170		cptr += 4;
171		kgdboc_use_kms = 1;
172	}
173
174	if (kgdboc_register_kbd(&cptr))
175		goto do_register;
176
177	p = tty_find_polling_driver(cptr, &tty_line);
178	if (!p)
179		goto noconfig;
180
181	cons = console_drivers;
182	while (cons) {
183		int idx;
184		if (cons->device && cons->device(cons, &idx) == p &&
185		    idx == tty_line) {
186			kgdboc_io_ops.is_console = 1;
187			break;
188		}
189		cons = cons->next;
190	}
191
192	kgdb_tty_driver = p;
193	kgdb_tty_line = tty_line;
194
195do_register:
196	err = kgdb_register_io_module(&kgdboc_io_ops);
197	if (err)
198		goto noconfig;
199
 
 
 
 
200	configured = 1;
201
202	return 0;
203
 
 
204noconfig:
 
205	config[0] = 0;
206	configured = 0;
207	cleanup_kgdboc();
208
209	return err;
210}
211
212static int __init init_kgdboc(void)
213{
214	/* Already configured? */
215	if (configured == 1)
216		return 0;
217
218	return configure_kgdboc();
219}
220
221static int kgdboc_get_char(void)
222{
223	if (!kgdb_tty_driver)
224		return -1;
225	return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver,
226						kgdb_tty_line);
227}
228
229static void kgdboc_put_char(u8 chr)
230{
231	if (!kgdb_tty_driver)
232		return;
233	kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver,
234					kgdb_tty_line, chr);
235}
236
237static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp)
238{
239	int len = strlen(kmessage);
240
241	if (len >= MAX_CONFIG_LEN) {
242		printk(KERN_ERR "kgdboc: config string too long\n");
243		return -ENOSPC;
244	}
245
246	/* Only copy in the string if the init function has not run yet */
247	if (configured < 0) {
248		strcpy(config, kmessage);
249		return 0;
250	}
251
252	if (kgdb_connected) {
253		printk(KERN_ERR
254		       "kgdboc: Cannot reconfigure while KGDB is connected.\n");
255
256		return -EBUSY;
257	}
258
259	strcpy(config, kmessage);
260	/* Chop out \n char as a result of echo */
261	if (config[len - 1] == '\n')
262		config[len - 1] = '\0';
263
264	if (configured == 1)
265		cleanup_kgdboc();
266
267	/* Go and configure with the new params. */
268	return configure_kgdboc();
269}
270
271static int dbg_restore_graphics;
272
273static void kgdboc_pre_exp_handler(void)
274{
275	if (!dbg_restore_graphics && kgdboc_use_kms) {
276		dbg_restore_graphics = 1;
277		con_debug_enter(vc_cons[fg_console].d);
278	}
279	/* Increment the module count when the debugger is active */
280	if (!kgdb_connected)
281		try_module_get(THIS_MODULE);
282}
283
284static void kgdboc_post_exp_handler(void)
285{
286	/* decrement the module count when the debugger detaches */
287	if (!kgdb_connected)
288		module_put(THIS_MODULE);
289	if (kgdboc_use_kms && dbg_restore_graphics) {
290		dbg_restore_graphics = 0;
291		con_debug_leave();
292	}
293	kgdboc_restore_input();
294}
295
296static struct kgdb_io kgdboc_io_ops = {
297	.name			= "kgdboc",
298	.read_char		= kgdboc_get_char,
299	.write_char		= kgdboc_put_char,
300	.pre_exception		= kgdboc_pre_exp_handler,
301	.post_exception		= kgdboc_post_exp_handler,
302};
303
304#ifdef CONFIG_KGDB_SERIAL_CONSOLE
305/* This is only available if kgdboc is a built in for early debugging */
306static int __init kgdboc_early_init(char *opt)
307{
308	/* save the first character of the config string because the
309	 * init routine can destroy it.
310	 */
311	char save_ch;
312
313	kgdboc_option_setup(opt);
314	save_ch = config[0];
315	init_kgdboc();
316	config[0] = save_ch;
317	return 0;
318}
319
320early_param("ekgdboc", kgdboc_early_init);
321#endif /* CONFIG_KGDB_SERIAL_CONSOLE */
322
323module_init(init_kgdboc);
324module_exit(cleanup_kgdboc);
325module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644);
326MODULE_PARM_DESC(kgdboc, "<serial_device>[,baud]");
327MODULE_DESCRIPTION("KGDB Console TTY Driver");
328MODULE_LICENSE("GPL");
v4.10.11
  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/kdb.h>
 18#include <linux/tty.h>
 19#include <linux/console.h>
 20#include <linux/vt_kern.h>
 21#include <linux/input.h>
 22#include <linux/module.h>
 23
 24#define MAX_CONFIG_LEN		40
 25
 26static struct kgdb_io		kgdboc_io_ops;
 27
 28/* -1 = init not run yet, 0 = unconfigured, 1 = configured. */
 29static int configured		= -1;
 30
 31static char config[MAX_CONFIG_LEN];
 32static struct kparam_string kps = {
 33	.string			= config,
 34	.maxlen			= MAX_CONFIG_LEN,
 35};
 36
 37static int kgdboc_use_kms;  /* 1 if we use kernel mode switching */
 38static struct tty_driver	*kgdb_tty_driver;
 39static int			kgdb_tty_line;
 40
 41#ifdef CONFIG_KDB_KEYBOARD
 42static int kgdboc_reset_connect(struct input_handler *handler,
 43				struct input_dev *dev,
 44				const struct input_device_id *id)
 45{
 46	input_reset_device(dev);
 47
 48	/* Return an error - we do not want to bind, just to reset */
 49	return -ENODEV;
 50}
 51
 52static void kgdboc_reset_disconnect(struct input_handle *handle)
 53{
 54	/* We do not expect anyone to actually bind to us */
 55	BUG();
 56}
 57
 58static const struct input_device_id kgdboc_reset_ids[] = {
 59	{
 60		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
 61		.evbit = { BIT_MASK(EV_KEY) },
 62	},
 63	{ }
 64};
 65
 66static struct input_handler kgdboc_reset_handler = {
 67	.connect	= kgdboc_reset_connect,
 68	.disconnect	= kgdboc_reset_disconnect,
 69	.name		= "kgdboc_reset",
 70	.id_table	= kgdboc_reset_ids,
 71};
 72
 73static DEFINE_MUTEX(kgdboc_reset_mutex);
 74
 75static void kgdboc_restore_input_helper(struct work_struct *dummy)
 76{
 77	/*
 78	 * We need to take a mutex to prevent several instances of
 79	 * this work running on different CPUs so they don't try
 80	 * to register again already registered handler.
 81	 */
 82	mutex_lock(&kgdboc_reset_mutex);
 83
 84	if (input_register_handler(&kgdboc_reset_handler) == 0)
 85		input_unregister_handler(&kgdboc_reset_handler);
 86
 87	mutex_unlock(&kgdboc_reset_mutex);
 88}
 89
 90static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
 91
 92static void kgdboc_restore_input(void)
 93{
 94	if (likely(system_state == SYSTEM_RUNNING))
 95		schedule_work(&kgdboc_restore_input_work);
 96}
 97
 98static int kgdboc_register_kbd(char **cptr)
 99{
100	if (strncmp(*cptr, "kbd", 3) == 0 ||
101		strncmp(*cptr, "kdb", 3) == 0) {
102		if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
103			kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
104			kdb_poll_idx++;
105			if (cptr[0][3] == ',')
106				*cptr += 4;
107			else
108				return 1;
109		}
110	}
111	return 0;
112}
113
114static void kgdboc_unregister_kbd(void)
115{
116	int i;
117
118	for (i = 0; i < kdb_poll_idx; i++) {
119		if (kdb_poll_funcs[i] == kdb_get_kbd_char) {
120			kdb_poll_idx--;
121			kdb_poll_funcs[i] = kdb_poll_funcs[kdb_poll_idx];
122			kdb_poll_funcs[kdb_poll_idx] = NULL;
123			i--;
124		}
125	}
126	flush_work(&kgdboc_restore_input_work);
127}
128#else /* ! CONFIG_KDB_KEYBOARD */
129#define kgdboc_register_kbd(x) 0
130#define kgdboc_unregister_kbd()
131#define kgdboc_restore_input()
132#endif /* ! CONFIG_KDB_KEYBOARD */
133
134static int kgdboc_option_setup(char *opt)
135{
136	if (strlen(opt) >= MAX_CONFIG_LEN) {
137		printk(KERN_ERR "kgdboc: config string too long\n");
138		return -ENOSPC;
139	}
140	strcpy(config, opt);
141
142	return 0;
143}
144
145__setup("kgdboc=", kgdboc_option_setup);
146
147static void cleanup_kgdboc(void)
148{
149	if (kgdb_unregister_nmi_console())
150		return;
151	kgdboc_unregister_kbd();
152	if (configured == 1)
153		kgdb_unregister_io_module(&kgdboc_io_ops);
154}
155
156static int configure_kgdboc(void)
157{
158	struct tty_driver *p;
159	int tty_line = 0;
160	int err;
161	char *cptr = config;
162	struct console *cons;
163
164	err = kgdboc_option_setup(config);
165	if (err || !strlen(config) || isspace(config[0]))
166		goto noconfig;
167
168	err = -ENODEV;
169	kgdboc_io_ops.is_console = 0;
170	kgdb_tty_driver = NULL;
171
172	kgdboc_use_kms = 0;
173	if (strncmp(cptr, "kms,", 4) == 0) {
174		cptr += 4;
175		kgdboc_use_kms = 1;
176	}
177
178	if (kgdboc_register_kbd(&cptr))
179		goto do_register;
180
181	p = tty_find_polling_driver(cptr, &tty_line);
182	if (!p)
183		goto noconfig;
184
185	cons = console_drivers;
186	while (cons) {
187		int idx;
188		if (cons->device && cons->device(cons, &idx) == p &&
189		    idx == tty_line) {
190			kgdboc_io_ops.is_console = 1;
191			break;
192		}
193		cons = cons->next;
194	}
195
196	kgdb_tty_driver = p;
197	kgdb_tty_line = tty_line;
198
199do_register:
200	err = kgdb_register_io_module(&kgdboc_io_ops);
201	if (err)
202		goto noconfig;
203
204	err = kgdb_register_nmi_console();
205	if (err)
206		goto nmi_con_failed;
207
208	configured = 1;
209
210	return 0;
211
212nmi_con_failed:
213	kgdb_unregister_io_module(&kgdboc_io_ops);
214noconfig:
215	kgdboc_unregister_kbd();
216	config[0] = 0;
217	configured = 0;
218	cleanup_kgdboc();
219
220	return err;
221}
222
223static int __init init_kgdboc(void)
224{
225	/* Already configured? */
226	if (configured == 1)
227		return 0;
228
229	return configure_kgdboc();
230}
231
232static int kgdboc_get_char(void)
233{
234	if (!kgdb_tty_driver)
235		return -1;
236	return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver,
237						kgdb_tty_line);
238}
239
240static void kgdboc_put_char(u8 chr)
241{
242	if (!kgdb_tty_driver)
243		return;
244	kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver,
245					kgdb_tty_line, chr);
246}
247
248static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp)
249{
250	int len = strlen(kmessage);
251
252	if (len >= MAX_CONFIG_LEN) {
253		printk(KERN_ERR "kgdboc: config string too long\n");
254		return -ENOSPC;
255	}
256
257	/* Only copy in the string if the init function has not run yet */
258	if (configured < 0) {
259		strcpy(config, kmessage);
260		return 0;
261	}
262
263	if (kgdb_connected) {
264		printk(KERN_ERR
265		       "kgdboc: Cannot reconfigure while KGDB is connected.\n");
266
267		return -EBUSY;
268	}
269
270	strcpy(config, kmessage);
271	/* Chop out \n char as a result of echo */
272	if (config[len - 1] == '\n')
273		config[len - 1] = '\0';
274
275	if (configured == 1)
276		cleanup_kgdboc();
277
278	/* Go and configure with the new params. */
279	return configure_kgdboc();
280}
281
282static int dbg_restore_graphics;
283
284static void kgdboc_pre_exp_handler(void)
285{
286	if (!dbg_restore_graphics && kgdboc_use_kms) {
287		dbg_restore_graphics = 1;
288		con_debug_enter(vc_cons[fg_console].d);
289	}
290	/* Increment the module count when the debugger is active */
291	if (!kgdb_connected)
292		try_module_get(THIS_MODULE);
293}
294
295static void kgdboc_post_exp_handler(void)
296{
297	/* decrement the module count when the debugger detaches */
298	if (!kgdb_connected)
299		module_put(THIS_MODULE);
300	if (kgdboc_use_kms && dbg_restore_graphics) {
301		dbg_restore_graphics = 0;
302		con_debug_leave();
303	}
304	kgdboc_restore_input();
305}
306
307static struct kgdb_io kgdboc_io_ops = {
308	.name			= "kgdboc",
309	.read_char		= kgdboc_get_char,
310	.write_char		= kgdboc_put_char,
311	.pre_exception		= kgdboc_pre_exp_handler,
312	.post_exception		= kgdboc_post_exp_handler,
313};
314
315#ifdef CONFIG_KGDB_SERIAL_CONSOLE
316/* This is only available if kgdboc is a built in for early debugging */
317static int __init kgdboc_early_init(char *opt)
318{
319	/* save the first character of the config string because the
320	 * init routine can destroy it.
321	 */
322	char save_ch;
323
324	kgdboc_option_setup(opt);
325	save_ch = config[0];
326	init_kgdboc();
327	config[0] = save_ch;
328	return 0;
329}
330
331early_param("ekgdboc", kgdboc_early_init);
332#endif /* CONFIG_KGDB_SERIAL_CONSOLE */
333
334module_init(init_kgdboc);
335module_exit(cleanup_kgdboc);
336module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644);
337MODULE_PARM_DESC(kgdboc, "<serial_device>[,baud]");
338MODULE_DESCRIPTION("KGDB Console TTY Driver");
339MODULE_LICENSE("GPL");