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