2 * proc_tty.c -- handles /proc/tty
4 * Copyright 1997, Theodore Ts'o
7 #include <asm/uaccess.h>
9 #include <linux/init.h>
10 #include <linux/errno.h>
11 #include <linux/sched.h>
12 #include <linux/proc_fs.h>
13 #include <linux/stat.h>
14 #include <linux/tty.h>
15 #include <asm/bitops.h>
17 extern struct tty_driver
*tty_drivers
; /* linked list of tty drivers */
18 extern struct tty_ldisc ldiscs
[];
21 static int tty_drivers_read_proc(char *page
, char **start
, off_t off
,
22 int count
, int *eof
, void *data
);
23 static int tty_ldiscs_read_proc(char *page
, char **start
, off_t off
,
24 int count
, int *eof
, void *data
);
27 * The /proc/tty directory inodes...
29 static struct proc_dir_entry
*proc_tty_ldisc
, *proc_tty_driver
;
32 * This is the handler for /proc/tty/drivers
34 static int tty_drivers_read_proc(char *page
, char **start
, off_t off
,
35 int count
, int *eof
, void *data
)
40 char range
[20], deftype
[20];
43 for (p
= tty_drivers
; p
; p
= p
->next
) {
45 sprintf(range
, "%d-%d", p
->minor_start
,
46 p
->minor_start
+ p
->num
- 1);
48 sprintf(range
, "%d", p
->minor_start
);
50 case TTY_DRIVER_TYPE_SYSTEM
:
51 if (p
->subtype
== SYSTEM_TYPE_TTY
)
52 type
= "system:/dev/tty";
53 else if (p
->subtype
== SYSTEM_TYPE_SYSCONS
)
54 type
= "system:console";
55 else if (p
->subtype
== SYSTEM_TYPE_CONSOLE
)
56 type
= "system:vtmaster";
60 case TTY_DRIVER_TYPE_CONSOLE
:
63 case TTY_DRIVER_TYPE_SERIAL
:
65 type
= "serial:callout";
69 case TTY_DRIVER_TYPE_PTY
:
70 if (p
->subtype
== PTY_TYPE_MASTER
)
72 else if (p
->subtype
== PTY_TYPE_SLAVE
)
78 sprintf(deftype
, "type:%d.%d", p
->type
, p
->subtype
);
82 len
+= sprintf(page
+len
, "%-20s /dev/%-8s %3d %7s %s\n",
83 p
->driver_name
? p
->driver_name
: "unknown",
84 p
->name
, p
->major
, range
, type
);
85 if (len
+begin
> off
+count
)
87 if (len
+begin
< off
) {
96 *start
= page
+ (begin
-off
);
97 return ((count
< begin
+len
-off
) ? count
: begin
+len
-off
);
101 * This is the handler for /proc/tty/ldiscs
103 static int tty_ldiscs_read_proc(char *page
, char **start
, off_t off
,
104 int count
, int *eof
, void *data
)
110 for (i
=0; i
< NR_LDISCS
; i
++) {
111 if (!(ldiscs
[i
].flags
& LDISC_FLAG_DEFINED
))
113 len
+= sprintf(page
+len
, "%-10s %2d\n",
114 ldiscs
[i
].name
? ldiscs
[i
].name
: "???", i
);
115 if (len
+begin
> off
+count
)
117 if (len
+begin
< off
) {
124 if (off
>= len
+begin
)
126 *start
= page
+ (begin
-off
);
127 return ((count
< begin
+len
-off
) ? count
: begin
+len
-off
);
131 * Thsi function is called by register_tty_driver() to handle
132 * registering the driver's /proc handler into /proc/tty/driver/<foo>
134 void proc_tty_register_driver(struct tty_driver
*driver
)
136 struct proc_dir_entry
*ent
;
138 if ((!driver
->read_proc
&& !driver
->write_proc
) ||
139 !driver
->driver_name
||
143 ent
= create_proc_entry(driver
->driver_name
, 0, proc_tty_driver
);
146 ent
->read_proc
= driver
->read_proc
;
147 ent
->write_proc
= driver
->write_proc
;
150 driver
->proc_entry
= ent
;
154 * This function is called by unregister_tty_driver()
156 void proc_tty_unregister_driver(struct tty_driver
*driver
)
158 struct proc_dir_entry
*ent
;
160 ent
= driver
->proc_entry
;
164 proc_unregister(proc_tty_driver
, ent
->low_ino
);
166 driver
->proc_entry
= 0;
171 * Called by proc_root_init() to initialize the /proc/tty subtree
173 void __init
proc_tty_init(void)
175 struct proc_dir_entry
*ent
;
177 ent
= create_proc_entry("tty", S_IFDIR
, 0);
180 proc_tty_ldisc
= create_proc_entry("tty/ldisc", S_IFDIR
, 0);
181 proc_tty_driver
= create_proc_entry("tty/driver", S_IFDIR
, 0);
183 ent
= create_proc_entry("tty/ldiscs", 0, 0);
184 ent
->read_proc
= tty_ldiscs_read_proc
;
186 ent
= create_proc_entry("tty/drivers", 0, 0);
187 ent
->read_proc
= tty_drivers_read_proc
;