Linux Audio

Check our new training course

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