^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2010 Werner Fink, Jiri Slaby
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/tty_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This is handler for /proc/consoles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static int show_console_dev(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) short flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) char name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) } con_flags[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) { CON_ENABLED, 'E' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) { CON_CONSDEV, 'C' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) { CON_BOOT, 'B' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) { CON_PRINTBUFFER, 'p' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) { CON_BRL, 'b' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) { CON_ANYTIME, 'a' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) char flags[ARRAY_SIZE(con_flags) + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct console *con = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned int a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) dev_t dev = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (con->device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) const struct tty_driver *driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) driver = con->device(con, &index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (driver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) dev = MKDEV(driver->major, driver->minor_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) dev += index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) for (a = 0; a < ARRAY_SIZE(con_flags); a++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) flags[a] = (con->flags & con_flags[a].flag) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) con_flags[a].name : ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) flags[a] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) seq_setwidth(m, 21 - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) seq_printf(m, "%s%d", con->name, con->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) seq_pad(m, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) con->write ? 'W' : '-', con->unblank ? 'U' : '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static void *c_start(struct seq_file *m, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct console *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) loff_t off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) console_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) for_each_console(con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (off++ == *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static void *c_next(struct seq_file *m, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct console *con = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return con->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static void c_stop(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) console_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static const struct seq_operations consoles_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .start = c_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .next = c_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .stop = c_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .show = show_console_dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static int __init proc_consoles_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) proc_create_seq("consoles", 0, NULL, &consoles_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) fs_initcall(proc_consoles_init);