ttynull.c (2386B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2019 Axis Communications AB 4 * 5 * Based on ttyprintk.c: 6 * Copyright (C) 2010 Samo Pogacnik 7 */ 8 9#include <linux/console.h> 10#include <linux/module.h> 11#include <linux/tty.h> 12 13static const struct tty_port_operations ttynull_port_ops; 14static struct tty_driver *ttynull_driver; 15static struct tty_port ttynull_port; 16 17static int ttynull_open(struct tty_struct *tty, struct file *filp) 18{ 19 return tty_port_open(&ttynull_port, tty, filp); 20} 21 22static void ttynull_close(struct tty_struct *tty, struct file *filp) 23{ 24 tty_port_close(&ttynull_port, tty, filp); 25} 26 27static void ttynull_hangup(struct tty_struct *tty) 28{ 29 tty_port_hangup(&ttynull_port); 30} 31 32static int ttynull_write(struct tty_struct *tty, const unsigned char *buf, 33 int count) 34{ 35 return count; 36} 37 38static unsigned int ttynull_write_room(struct tty_struct *tty) 39{ 40 return 65536; 41} 42 43static const struct tty_operations ttynull_ops = { 44 .open = ttynull_open, 45 .close = ttynull_close, 46 .hangup = ttynull_hangup, 47 .write = ttynull_write, 48 .write_room = ttynull_write_room, 49}; 50 51static struct tty_driver *ttynull_device(struct console *c, int *index) 52{ 53 *index = 0; 54 return ttynull_driver; 55} 56 57static struct console ttynull_console = { 58 .name = "ttynull", 59 .device = ttynull_device, 60}; 61 62static int __init ttynull_init(void) 63{ 64 struct tty_driver *driver; 65 int ret; 66 67 driver = tty_alloc_driver(1, 68 TTY_DRIVER_RESET_TERMIOS | 69 TTY_DRIVER_REAL_RAW | 70 TTY_DRIVER_UNNUMBERED_NODE); 71 if (IS_ERR(driver)) 72 return PTR_ERR(driver); 73 74 tty_port_init(&ttynull_port); 75 ttynull_port.ops = &ttynull_port_ops; 76 77 driver->driver_name = "ttynull"; 78 driver->name = "ttynull"; 79 driver->type = TTY_DRIVER_TYPE_CONSOLE; 80 driver->init_termios = tty_std_termios; 81 driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET; 82 tty_set_operations(driver, &ttynull_ops); 83 tty_port_link_device(&ttynull_port, driver, 0); 84 85 ret = tty_register_driver(driver); 86 if (ret < 0) { 87 tty_driver_kref_put(driver); 88 tty_port_destroy(&ttynull_port); 89 return ret; 90 } 91 92 ttynull_driver = driver; 93 register_console(&ttynull_console); 94 95 return 0; 96} 97 98static void __exit ttynull_exit(void) 99{ 100 unregister_console(&ttynull_console); 101 tty_unregister_driver(ttynull_driver); 102 tty_driver_kref_put(ttynull_driver); 103 tty_port_destroy(&ttynull_port); 104} 105 106module_init(ttynull_init); 107module_exit(ttynull_exit); 108 109MODULE_LICENSE("GPL v2");