0001
0002
0003
0004
0005
0006
0007 #include <linux/module.h>
0008 #include <linux/init.h>
0009 #include <linux/errno.h>
0010 #include <linux/time.h>
0011 #include <linux/proc_fs.h>
0012 #include <linux/stat.h>
0013 #include <linux/tty.h>
0014 #include <linux/seq_file.h>
0015 #include <linux/bitops.h>
0016 #include "internal.h"
0017
0018
0019
0020
0021 static struct proc_dir_entry *proc_tty_driver;
0022
0023
0024
0025
0026 static void show_tty_range(struct seq_file *m, struct tty_driver *p,
0027 dev_t from, int num)
0028 {
0029 seq_printf(m, "%-20s ", p->driver_name ? p->driver_name : "unknown");
0030 seq_printf(m, "/dev/%-8s ", p->name);
0031 if (p->num > 1) {
0032 seq_printf(m, "%3d %d-%d ", MAJOR(from), MINOR(from),
0033 MINOR(from) + num - 1);
0034 } else {
0035 seq_printf(m, "%3d %7d ", MAJOR(from), MINOR(from));
0036 }
0037 switch (p->type) {
0038 case TTY_DRIVER_TYPE_SYSTEM:
0039 seq_puts(m, "system");
0040 if (p->subtype == SYSTEM_TYPE_TTY)
0041 seq_puts(m, ":/dev/tty");
0042 else if (p->subtype == SYSTEM_TYPE_SYSCONS)
0043 seq_puts(m, ":console");
0044 else if (p->subtype == SYSTEM_TYPE_CONSOLE)
0045 seq_puts(m, ":vtmaster");
0046 break;
0047 case TTY_DRIVER_TYPE_CONSOLE:
0048 seq_puts(m, "console");
0049 break;
0050 case TTY_DRIVER_TYPE_SERIAL:
0051 seq_puts(m, "serial");
0052 break;
0053 case TTY_DRIVER_TYPE_PTY:
0054 if (p->subtype == PTY_TYPE_MASTER)
0055 seq_puts(m, "pty:master");
0056 else if (p->subtype == PTY_TYPE_SLAVE)
0057 seq_puts(m, "pty:slave");
0058 else
0059 seq_puts(m, "pty");
0060 break;
0061 default:
0062 seq_printf(m, "type:%d.%d", p->type, p->subtype);
0063 }
0064 seq_putc(m, '\n');
0065 }
0066
0067 static int show_tty_driver(struct seq_file *m, void *v)
0068 {
0069 struct tty_driver *p = list_entry(v, struct tty_driver, tty_drivers);
0070 dev_t from = MKDEV(p->major, p->minor_start);
0071 dev_t to = from + p->num;
0072
0073 if (&p->tty_drivers == tty_drivers.next) {
0074
0075 seq_printf(m, "%-20s /dev/%-8s ", "/dev/tty", "tty");
0076 seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 0);
0077 seq_puts(m, "system:/dev/tty\n");
0078 seq_printf(m, "%-20s /dev/%-8s ", "/dev/console", "console");
0079 seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 1);
0080 seq_puts(m, "system:console\n");
0081 #ifdef CONFIG_UNIX98_PTYS
0082 seq_printf(m, "%-20s /dev/%-8s ", "/dev/ptmx", "ptmx");
0083 seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 2);
0084 seq_puts(m, "system\n");
0085 #endif
0086 #ifdef CONFIG_VT
0087 seq_printf(m, "%-20s /dev/%-8s ", "/dev/vc/0", "vc/0");
0088 seq_printf(m, "%3d %7d ", TTY_MAJOR, 0);
0089 seq_puts(m, "system:vtmaster\n");
0090 #endif
0091 }
0092
0093 while (MAJOR(from) < MAJOR(to)) {
0094 dev_t next = MKDEV(MAJOR(from)+1, 0);
0095 show_tty_range(m, p, from, next - from);
0096 from = next;
0097 }
0098 if (from != to)
0099 show_tty_range(m, p, from, to - from);
0100 return 0;
0101 }
0102
0103
0104 static void *t_start(struct seq_file *m, loff_t *pos)
0105 {
0106 mutex_lock(&tty_mutex);
0107 return seq_list_start(&tty_drivers, *pos);
0108 }
0109
0110 static void *t_next(struct seq_file *m, void *v, loff_t *pos)
0111 {
0112 return seq_list_next(v, &tty_drivers, pos);
0113 }
0114
0115 static void t_stop(struct seq_file *m, void *v)
0116 {
0117 mutex_unlock(&tty_mutex);
0118 }
0119
0120 static const struct seq_operations tty_drivers_op = {
0121 .start = t_start,
0122 .next = t_next,
0123 .stop = t_stop,
0124 .show = show_tty_driver
0125 };
0126
0127
0128
0129
0130
0131 void proc_tty_register_driver(struct tty_driver *driver)
0132 {
0133 struct proc_dir_entry *ent;
0134
0135 if (!driver->driver_name || driver->proc_entry ||
0136 !driver->ops->proc_show)
0137 return;
0138
0139 ent = proc_create_single_data(driver->driver_name, 0, proc_tty_driver,
0140 driver->ops->proc_show, driver);
0141 driver->proc_entry = ent;
0142 }
0143
0144
0145
0146
0147 void proc_tty_unregister_driver(struct tty_driver *driver)
0148 {
0149 struct proc_dir_entry *ent;
0150
0151 ent = driver->proc_entry;
0152 if (!ent)
0153 return;
0154
0155 remove_proc_entry(ent->name, proc_tty_driver);
0156
0157 driver->proc_entry = NULL;
0158 }
0159
0160
0161
0162
0163 void __init proc_tty_init(void)
0164 {
0165 if (!proc_mkdir("tty", NULL))
0166 return;
0167 proc_mkdir("tty/ldisc", NULL);
0168
0169
0170
0171
0172
0173
0174 proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL);
0175 proc_create_seq("tty/ldiscs", 0, NULL, &tty_ldiscs_seq_ops);
0176 proc_create_seq("tty/drivers", 0, NULL, &tty_drivers_op);
0177 }