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