18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2010 Werner Fink, Jiri Slaby 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/console.h> 78c2ecf20Sopenharmony_ci#include <linux/kernel.h> 88c2ecf20Sopenharmony_ci#include <linux/proc_fs.h> 98c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 108c2ecf20Sopenharmony_ci#include <linux/tty_driver.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/* 138c2ecf20Sopenharmony_ci * This is handler for /proc/consoles 148c2ecf20Sopenharmony_ci */ 158c2ecf20Sopenharmony_cistatic int show_console_dev(struct seq_file *m, void *v) 168c2ecf20Sopenharmony_ci{ 178c2ecf20Sopenharmony_ci static const struct { 188c2ecf20Sopenharmony_ci short flag; 198c2ecf20Sopenharmony_ci char name; 208c2ecf20Sopenharmony_ci } con_flags[] = { 218c2ecf20Sopenharmony_ci { CON_ENABLED, 'E' }, 228c2ecf20Sopenharmony_ci { CON_CONSDEV, 'C' }, 238c2ecf20Sopenharmony_ci { CON_BOOT, 'B' }, 248c2ecf20Sopenharmony_ci { CON_PRINTBUFFER, 'p' }, 258c2ecf20Sopenharmony_ci { CON_BRL, 'b' }, 268c2ecf20Sopenharmony_ci { CON_ANYTIME, 'a' }, 278c2ecf20Sopenharmony_ci }; 288c2ecf20Sopenharmony_ci char flags[ARRAY_SIZE(con_flags) + 1]; 298c2ecf20Sopenharmony_ci struct console *con = v; 308c2ecf20Sopenharmony_ci unsigned int a; 318c2ecf20Sopenharmony_ci dev_t dev = 0; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci if (con->device) { 348c2ecf20Sopenharmony_ci const struct tty_driver *driver; 358c2ecf20Sopenharmony_ci int index; 368c2ecf20Sopenharmony_ci driver = con->device(con, &index); 378c2ecf20Sopenharmony_ci if (driver) { 388c2ecf20Sopenharmony_ci dev = MKDEV(driver->major, driver->minor_start); 398c2ecf20Sopenharmony_ci dev += index; 408c2ecf20Sopenharmony_ci } 418c2ecf20Sopenharmony_ci } 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci for (a = 0; a < ARRAY_SIZE(con_flags); a++) 448c2ecf20Sopenharmony_ci flags[a] = (con->flags & con_flags[a].flag) ? 458c2ecf20Sopenharmony_ci con_flags[a].name : ' '; 468c2ecf20Sopenharmony_ci flags[a] = 0; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci seq_setwidth(m, 21 - 1); 498c2ecf20Sopenharmony_ci seq_printf(m, "%s%d", con->name, con->index); 508c2ecf20Sopenharmony_ci seq_pad(m, ' '); 518c2ecf20Sopenharmony_ci seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-', 528c2ecf20Sopenharmony_ci con->write ? 'W' : '-', con->unblank ? 'U' : '-', 538c2ecf20Sopenharmony_ci flags); 548c2ecf20Sopenharmony_ci if (dev) 558c2ecf20Sopenharmony_ci seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev)); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci seq_putc(m, '\n'); 588c2ecf20Sopenharmony_ci return 0; 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic void *c_start(struct seq_file *m, loff_t *pos) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci struct console *con; 648c2ecf20Sopenharmony_ci loff_t off = 0; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci console_lock(); 678c2ecf20Sopenharmony_ci for_each_console(con) 688c2ecf20Sopenharmony_ci if (off++ == *pos) 698c2ecf20Sopenharmony_ci break; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci return con; 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic void *c_next(struct seq_file *m, void *v, loff_t *pos) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci struct console *con = v; 778c2ecf20Sopenharmony_ci ++*pos; 788c2ecf20Sopenharmony_ci return con->next; 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic void c_stop(struct seq_file *m, void *v) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci console_unlock(); 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic const struct seq_operations consoles_op = { 878c2ecf20Sopenharmony_ci .start = c_start, 888c2ecf20Sopenharmony_ci .next = c_next, 898c2ecf20Sopenharmony_ci .stop = c_stop, 908c2ecf20Sopenharmony_ci .show = show_console_dev 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic int __init proc_consoles_init(void) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci proc_create_seq("consoles", 0, NULL, &consoles_op); 968c2ecf20Sopenharmony_ci return 0; 978c2ecf20Sopenharmony_ci} 988c2ecf20Sopenharmony_cifs_initcall(proc_consoles_init); 99