xref: /linux-6.15/drivers/tty/ttynull.c (revision f0a17485)
13117ff13SVincent Whitchurch // SPDX-License-Identifier: GPL-2.0
23117ff13SVincent Whitchurch /*
33117ff13SVincent Whitchurch  * Copyright (C) 2019 Axis Communications AB
43117ff13SVincent Whitchurch  *
53117ff13SVincent Whitchurch  * Based on ttyprintk.c:
63117ff13SVincent Whitchurch  *  Copyright (C) 2010 Samo Pogacnik
73117ff13SVincent Whitchurch  */
83117ff13SVincent Whitchurch 
93117ff13SVincent Whitchurch #include <linux/console.h>
103117ff13SVincent Whitchurch #include <linux/module.h>
113117ff13SVincent Whitchurch #include <linux/tty.h>
123117ff13SVincent Whitchurch 
133117ff13SVincent Whitchurch static const struct tty_port_operations ttynull_port_ops;
143117ff13SVincent Whitchurch static struct tty_driver *ttynull_driver;
153117ff13SVincent Whitchurch static struct tty_port ttynull_port;
163117ff13SVincent Whitchurch 
ttynull_open(struct tty_struct * tty,struct file * filp)173117ff13SVincent Whitchurch static int ttynull_open(struct tty_struct *tty, struct file *filp)
183117ff13SVincent Whitchurch {
193117ff13SVincent Whitchurch 	return tty_port_open(&ttynull_port, tty, filp);
203117ff13SVincent Whitchurch }
213117ff13SVincent Whitchurch 
ttynull_close(struct tty_struct * tty,struct file * filp)223117ff13SVincent Whitchurch static void ttynull_close(struct tty_struct *tty, struct file *filp)
233117ff13SVincent Whitchurch {
243117ff13SVincent Whitchurch 	tty_port_close(&ttynull_port, tty, filp);
253117ff13SVincent Whitchurch }
263117ff13SVincent Whitchurch 
ttynull_hangup(struct tty_struct * tty)273117ff13SVincent Whitchurch static void ttynull_hangup(struct tty_struct *tty)
283117ff13SVincent Whitchurch {
293117ff13SVincent Whitchurch 	tty_port_hangup(&ttynull_port);
303117ff13SVincent Whitchurch }
313117ff13SVincent Whitchurch 
ttynull_write(struct tty_struct * tty,const u8 * buf,size_t count)3295713967SJiri Slaby (SUSE) static ssize_t ttynull_write(struct tty_struct *tty, const u8 *buf,
3395713967SJiri Slaby (SUSE) 			     size_t count)
343117ff13SVincent Whitchurch {
353117ff13SVincent Whitchurch 	return count;
363117ff13SVincent Whitchurch }
373117ff13SVincent Whitchurch 
ttynull_write_room(struct tty_struct * tty)3803b3b1a2SJiri Slaby static unsigned int ttynull_write_room(struct tty_struct *tty)
393117ff13SVincent Whitchurch {
403117ff13SVincent Whitchurch 	return 65536;
413117ff13SVincent Whitchurch }
423117ff13SVincent Whitchurch 
433117ff13SVincent Whitchurch static const struct tty_operations ttynull_ops = {
443117ff13SVincent Whitchurch 	.open = ttynull_open,
453117ff13SVincent Whitchurch 	.close = ttynull_close,
463117ff13SVincent Whitchurch 	.hangup = ttynull_hangup,
473117ff13SVincent Whitchurch 	.write = ttynull_write,
483117ff13SVincent Whitchurch 	.write_room = ttynull_write_room,
493117ff13SVincent Whitchurch };
503117ff13SVincent Whitchurch 
ttynull_device(struct console * c,int * index)513117ff13SVincent Whitchurch static struct tty_driver *ttynull_device(struct console *c, int *index)
523117ff13SVincent Whitchurch {
533117ff13SVincent Whitchurch 	*index = 0;
543117ff13SVincent Whitchurch 	return ttynull_driver;
553117ff13SVincent Whitchurch }
563117ff13SVincent Whitchurch 
573117ff13SVincent Whitchurch static struct console ttynull_console = {
583117ff13SVincent Whitchurch 	.name = "ttynull",
593117ff13SVincent Whitchurch 	.device = ttynull_device,
603117ff13SVincent Whitchurch };
613117ff13SVincent Whitchurch 
ttynull_init(void)623117ff13SVincent Whitchurch static int __init ttynull_init(void)
633117ff13SVincent Whitchurch {
643117ff13SVincent Whitchurch 	struct tty_driver *driver;
653117ff13SVincent Whitchurch 	int ret;
663117ff13SVincent Whitchurch 
673117ff13SVincent Whitchurch 	driver = tty_alloc_driver(1,
683117ff13SVincent Whitchurch 		TTY_DRIVER_RESET_TERMIOS |
693117ff13SVincent Whitchurch 		TTY_DRIVER_REAL_RAW |
703117ff13SVincent Whitchurch 		TTY_DRIVER_UNNUMBERED_NODE);
713117ff13SVincent Whitchurch 	if (IS_ERR(driver))
723117ff13SVincent Whitchurch 		return PTR_ERR(driver);
733117ff13SVincent Whitchurch 
743117ff13SVincent Whitchurch 	tty_port_init(&ttynull_port);
753117ff13SVincent Whitchurch 	ttynull_port.ops = &ttynull_port_ops;
763117ff13SVincent Whitchurch 
773117ff13SVincent Whitchurch 	driver->driver_name = "ttynull";
783117ff13SVincent Whitchurch 	driver->name = "ttynull";
793117ff13SVincent Whitchurch 	driver->type = TTY_DRIVER_TYPE_CONSOLE;
803117ff13SVincent Whitchurch 	driver->init_termios = tty_std_termios;
813117ff13SVincent Whitchurch 	driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET;
823117ff13SVincent Whitchurch 	tty_set_operations(driver, &ttynull_ops);
833117ff13SVincent Whitchurch 	tty_port_link_device(&ttynull_port, driver, 0);
843117ff13SVincent Whitchurch 
853117ff13SVincent Whitchurch 	ret = tty_register_driver(driver);
863117ff13SVincent Whitchurch 	if (ret < 0) {
879f90a4ddSJiri Slaby 		tty_driver_kref_put(driver);
883117ff13SVincent Whitchurch 		tty_port_destroy(&ttynull_port);
893117ff13SVincent Whitchurch 		return ret;
903117ff13SVincent Whitchurch 	}
913117ff13SVincent Whitchurch 
923117ff13SVincent Whitchurch 	ttynull_driver = driver;
933117ff13SVincent Whitchurch 	register_console(&ttynull_console);
943117ff13SVincent Whitchurch 
953117ff13SVincent Whitchurch 	return 0;
963117ff13SVincent Whitchurch }
973117ff13SVincent Whitchurch 
ttynull_exit(void)983117ff13SVincent Whitchurch static void __exit ttynull_exit(void)
993117ff13SVincent Whitchurch {
1003117ff13SVincent Whitchurch 	unregister_console(&ttynull_console);
1013117ff13SVincent Whitchurch 	tty_unregister_driver(ttynull_driver);
1029f90a4ddSJiri Slaby 	tty_driver_kref_put(ttynull_driver);
1033117ff13SVincent Whitchurch 	tty_port_destroy(&ttynull_port);
1043117ff13SVincent Whitchurch }
1053117ff13SVincent Whitchurch 
1063117ff13SVincent Whitchurch module_init(ttynull_init);
1073117ff13SVincent Whitchurch module_exit(ttynull_exit);
1083117ff13SVincent Whitchurch 
109*f0a17485SJeff Johnson MODULE_DESCRIPTION("NULL TTY driver");
1103117ff13SVincent Whitchurch MODULE_LICENSE("GPL v2");
111