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 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 if (con->device) { 34 const struct tty_driver *driver; 35 int index; 36 driver = con->device(con, &index); 37 if (driver) { 38 dev = MKDEV(driver->major, driver->minor_start); 39 dev += index; 40 } 41 } 42 43 for (a = 0; a < ARRAY_SIZE(con_flags); a++) 44 flags[a] = (con->flags & con_flags[a].flag) ? 45 con_flags[a].name : ' '; 46 flags[a] = 0; 47 48 seq_setwidth(m, 21 - 1); 49 seq_printf(m, "%s%d", con->name, con->index); 50 seq_pad(m, ' '); 51 seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-', 52 con->write ? 'W' : '-', con->unblank ? 'U' : '-', 53 flags); 54 if (dev) 55 seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev)); 56 57 seq_putc(m, '\n'); 58 return 0; 59 } 60 61 static void *c_start(struct seq_file *m, loff_t *pos) 62 { 63 struct console *con; 64 loff_t off = 0; 65 66 console_lock(); 67 for_each_console(con) 68 if (off++ == *pos) 69 break; 70 71 return con; 72 } 73 74 static void *c_next(struct seq_file *m, void *v, loff_t *pos) 75 { 76 struct console *con = v; 77 ++*pos; 78 return con->next; 79 } 80 81 static void c_stop(struct seq_file *m, void *v) 82 { 83 console_unlock(); 84 } 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 static int __init proc_consoles_init(void) 94 { 95 proc_create_seq("consoles", 0, NULL, &consoles_op); 96 return 0; 97 } 98 fs_initcall(proc_consoles_init); 99