ttynull.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. #include <linux/console.h>
  9. #include <linux/module.h>
  10. #include <linux/tty.h>
  11. static const struct tty_port_operations ttynull_port_ops;
  12. static struct tty_driver *ttynull_driver;
  13. static struct tty_port ttynull_port;
  14. static int ttynull_open(struct tty_struct *tty, struct file *filp)
  15. {
  16. return tty_port_open(&ttynull_port, tty, filp);
  17. }
  18. static void ttynull_close(struct tty_struct *tty, struct file *filp)
  19. {
  20. tty_port_close(&ttynull_port, tty, filp);
  21. }
  22. static void ttynull_hangup(struct tty_struct *tty)
  23. {
  24. tty_port_hangup(&ttynull_port);
  25. }
  26. static int ttynull_write(struct tty_struct *tty, const unsigned char *buf,
  27. int count)
  28. {
  29. return count;
  30. }
  31. static int ttynull_write_room(struct tty_struct *tty)
  32. {
  33. return 65536;
  34. }
  35. static const struct tty_operations ttynull_ops = {
  36. .open = ttynull_open,
  37. .close = ttynull_close,
  38. .hangup = ttynull_hangup,
  39. .write = ttynull_write,
  40. .write_room = ttynull_write_room,
  41. };
  42. static struct tty_driver *ttynull_device(struct console *c, int *index)
  43. {
  44. *index = 0;
  45. return ttynull_driver;
  46. }
  47. static struct console ttynull_console = {
  48. .name = "ttynull",
  49. .device = ttynull_device,
  50. };
  51. static int __init ttynull_init(void)
  52. {
  53. struct tty_driver *driver;
  54. int ret;
  55. driver = tty_alloc_driver(1,
  56. TTY_DRIVER_RESET_TERMIOS |
  57. TTY_DRIVER_REAL_RAW |
  58. TTY_DRIVER_UNNUMBERED_NODE);
  59. if (IS_ERR(driver))
  60. return PTR_ERR(driver);
  61. tty_port_init(&ttynull_port);
  62. ttynull_port.ops = &ttynull_port_ops;
  63. driver->driver_name = "ttynull";
  64. driver->name = "ttynull";
  65. driver->type = TTY_DRIVER_TYPE_CONSOLE;
  66. driver->init_termios = tty_std_termios;
  67. driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET;
  68. tty_set_operations(driver, &ttynull_ops);
  69. tty_port_link_device(&ttynull_port, driver, 0);
  70. ret = tty_register_driver(driver);
  71. if (ret < 0) {
  72. put_tty_driver(driver);
  73. tty_port_destroy(&ttynull_port);
  74. return ret;
  75. }
  76. ttynull_driver = driver;
  77. register_console(&ttynull_console);
  78. return 0;
  79. }
  80. static void __exit ttynull_exit(void)
  81. {
  82. unregister_console(&ttynull_console);
  83. tty_unregister_driver(ttynull_driver);
  84. put_tty_driver(ttynull_driver);
  85. tty_port_destroy(&ttynull_port);
  86. }
  87. module_init(ttynull_init);
  88. module_exit(ttynull_exit);
  89. MODULE_LICENSE("GPL v2");