Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2010 Werner Fink, Jiri Slaby
0004  */
0005 
0006 #include <linux/console.h>
0007 #include <linux/kernel.h>
0008 #include <linux/proc_fs.h>
0009 #include <linux/seq_file.h>
0010 #include <linux/tty_driver.h>
0011 
0012 /*
0013  * This is handler for /proc/consoles
0014  */
0015 static int show_console_dev(struct seq_file *m, void *v)
0016 {
0017     static const struct {
0018         short flag;
0019         char name;
0020     } con_flags[] = {
0021         { CON_ENABLED,      'E' },
0022         { CON_CONSDEV,      'C' },
0023         { CON_BOOT,     'B' },
0024         { CON_PRINTBUFFER,  'p' },
0025         { CON_BRL,      'b' },
0026         { CON_ANYTIME,      'a' },
0027     };
0028     char flags[ARRAY_SIZE(con_flags) + 1];
0029     struct console *con = v;
0030     unsigned int a;
0031     dev_t dev = 0;
0032 
0033     if (con->device) {
0034         const struct tty_driver *driver;
0035         int index;
0036         driver = con->device(con, &index);
0037         if (driver) {
0038             dev = MKDEV(driver->major, driver->minor_start);
0039             dev += index;
0040         }
0041     }
0042 
0043     for (a = 0; a < ARRAY_SIZE(con_flags); a++)
0044         flags[a] = (con->flags & con_flags[a].flag) ?
0045             con_flags[a].name : ' ';
0046     flags[a] = 0;
0047 
0048     seq_setwidth(m, 21 - 1);
0049     seq_printf(m, "%s%d", con->name, con->index);
0050     seq_pad(m, ' ');
0051     seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-',
0052             con->write ? 'W' : '-', con->unblank ? 'U' : '-',
0053             flags);
0054     if (dev)
0055         seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev));
0056 
0057     seq_putc(m, '\n');
0058     return 0;
0059 }
0060 
0061 static void *c_start(struct seq_file *m, loff_t *pos)
0062 {
0063     struct console *con;
0064     loff_t off = 0;
0065 
0066     console_lock();
0067     for_each_console(con)
0068         if (off++ == *pos)
0069             break;
0070 
0071     return con;
0072 }
0073 
0074 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
0075 {
0076     struct console *con = v;
0077     ++*pos;
0078     return con->next;
0079 }
0080 
0081 static void c_stop(struct seq_file *m, void *v)
0082 {
0083     console_unlock();
0084 }
0085 
0086 static const struct seq_operations consoles_op = {
0087     .start  = c_start,
0088     .next   = c_next,
0089     .stop   = c_stop,
0090     .show   = show_console_dev
0091 };
0092 
0093 static int __init proc_consoles_init(void)
0094 {
0095     proc_create_seq("consoles", 0, NULL, &consoles_op);
0096     return 0;
0097 }
0098 fs_initcall(proc_consoles_init);