diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 22:59:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 22:59:04 -0400 |
commit | 73ecf3a6e3f0206bf56a0fefe3b3eda042fb7034 (patch) | |
tree | 866f0ebb2b148479e93b5ac955097b1cc94ceb4e /fs/proc | |
parent | b9da0571050c09863e59f94d0b8594a290d61b88 (diff) | |
parent | cd3ecad19aea8debae9a48b53de2ec7a571f24e9 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: (49 commits)
serial8250: ratelimit "too much work" error
serial: bfin_sport_uart: speed up sport RX sample rate to be 3% faster
serial: abstraction for 8250 legacy ports
serial/imx: check that the buffer is non-empty before sending it out
serial: mfd: add more baud rates support
jsm: Remove the uart port on errors
Alchemy: Add UART PM methods.
8250: allow platforms to override PM hook.
altera_uart: Don't use plain integer as NULL pointer
altera_uart: Fix missing prototype for registering an early console
altera_uart: Fixup type usage of port flags
altera_uart: Make it possible to use Altera UART and 8250 ports together
altera_uart: Add support for different address strides
altera_uart: Add support for getting mapbase and IRQ from resources
altera_uart: Add support for polling mode (IRQ-less)
serial: Factor out uart_poll_timeout() from 8250 driver
serial: mark the 8250 driver as maintained
serial: 8250: Don't delay after transmitter is ready.
tty: MAINTAINERS: add drivers/serial/jsm/ as maintained driver
vcs: invoke the vt update callback when /dev/vcs* is written to
...
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/proc_tty.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c index 83adcc869437..dc44f94022f1 100644 --- a/fs/proc/proc_tty.c +++ b/fs/proc/proc_tty.c | |||
@@ -12,7 +12,10 @@ | |||
12 | #include <linux/proc_fs.h> | 12 | #include <linux/proc_fs.h> |
13 | #include <linux/stat.h> | 13 | #include <linux/stat.h> |
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | #include <linux/tty_driver.h> | ||
16 | #include <linux/console.h> | ||
15 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
18 | #include <linux/fdtable.h> | ||
16 | #include <linux/bitops.h> | 19 | #include <linux/bitops.h> |
17 | 20 | ||
18 | /* | 21 | /* |
@@ -137,6 +140,160 @@ static const struct file_operations proc_tty_drivers_operations = { | |||
137 | }; | 140 | }; |
138 | 141 | ||
139 | /* | 142 | /* |
143 | * The device ID of file descriptor 0 of the current reading | ||
144 | * task if a character device... | ||
145 | */ | ||
146 | static dev_t current_dev; | ||
147 | |||
148 | /* | ||
149 | * This is the handler for /proc/tty/consoles | ||
150 | */ | ||
151 | static int show_console_dev(struct seq_file *m, void *v) | ||
152 | { | ||
153 | const struct tty_driver *driver; | ||
154 | struct console *con; | ||
155 | int index, len; | ||
156 | char flags[10]; | ||
157 | dev_t dev; | ||
158 | |||
159 | if (v == SEQ_START_TOKEN) | ||
160 | return 0; | ||
161 | con = (struct console *)v; | ||
162 | if (!con) | ||
163 | return 0; | ||
164 | driver = con->device(con, &index); | ||
165 | if (!driver) | ||
166 | return 0; | ||
167 | dev = MKDEV(driver->major, driver->minor_start) + index; | ||
168 | |||
169 | index = 0; | ||
170 | if (con->flags & CON_ENABLED) | ||
171 | flags[index++] = 'E'; | ||
172 | if (con->flags & CON_CONSDEV) | ||
173 | flags[index++] = 'C'; | ||
174 | if (con->flags & CON_BOOT) | ||
175 | flags[index++] = 'B'; | ||
176 | if (con->flags & CON_PRINTBUFFER) | ||
177 | flags[index++] = 'p'; | ||
178 | if (con->flags & CON_BRL) | ||
179 | flags[index++] = 'b'; | ||
180 | if (con->flags & CON_ANYTIME) | ||
181 | flags[index++] = 'a'; | ||
182 | if (current_dev == dev) | ||
183 | flags[index++] = '*'; | ||
184 | flags[index] = 0; | ||
185 | |||
186 | seq_printf(m, "%s%d%n", con->name, con->index, &len); | ||
187 | len = 21 - len; | ||
188 | if (len < 1) | ||
189 | len = 1; | ||
190 | seq_printf(m, "%*c", len, ' '); | ||
191 | seq_printf(m, "%c%c%c (%s)%n", con->read ? 'R' : '-', | ||
192 | con->write ? 'W' : '-', con->unblank ? 'U' : '-', | ||
193 | flags, &len); | ||
194 | len = 13 - len; | ||
195 | if (len < 1) | ||
196 | len = 1; | ||
197 | seq_printf(m, "%*c%4d:%d\n", len, ' ', MAJOR(dev), MINOR(dev)); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | /* iterator for consoles */ | ||
203 | static void *c_start(struct seq_file *m, loff_t *pos) | ||
204 | { | ||
205 | struct console *con; | ||
206 | loff_t off = 0; | ||
207 | |||
208 | if (*pos == 0) | ||
209 | return SEQ_START_TOKEN; | ||
210 | |||
211 | acquire_console_sem(); | ||
212 | for (con = console_drivers; con; con = con->next) { | ||
213 | if (!con->device) | ||
214 | continue; | ||
215 | if (++off == *pos) | ||
216 | break; | ||
217 | } | ||
218 | release_console_sem(); | ||
219 | |||
220 | return con; | ||
221 | } | ||
222 | |||
223 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) | ||
224 | { | ||
225 | struct console *con; | ||
226 | |||
227 | acquire_console_sem(); | ||
228 | if (v == SEQ_START_TOKEN) | ||
229 | con = console_drivers; | ||
230 | else | ||
231 | con = ((struct console *)v)->next; | ||
232 | for (; con; con = con->next) { | ||
233 | if (!con->device) | ||
234 | continue; | ||
235 | ++*pos; | ||
236 | break; | ||
237 | } | ||
238 | release_console_sem(); | ||
239 | |||
240 | return con; | ||
241 | } | ||
242 | |||
243 | static void c_stop(struct seq_file *m, void *v) | ||
244 | { | ||
245 | } | ||
246 | |||
247 | static const struct seq_operations tty_consoles_op = { | ||
248 | .start = c_start, | ||
249 | .next = c_next, | ||
250 | .stop = c_stop, | ||
251 | .show = show_console_dev | ||
252 | }; | ||
253 | |||
254 | /* | ||
255 | * Used for open /proc/tty/consoles. Before this detect | ||
256 | * the device ID of file descriptor 0 of the current | ||
257 | * reading task if a character device... | ||
258 | */ | ||
259 | static int tty_consoles_open(struct inode *inode, struct file *file) | ||
260 | { | ||
261 | struct files_struct *curfiles; | ||
262 | |||
263 | current_dev = 0; | ||
264 | curfiles = get_files_struct(current); | ||
265 | if (curfiles) { | ||
266 | const struct file *curfp; | ||
267 | spin_lock(&curfiles->file_lock); | ||
268 | curfp = fcheck_files(curfiles, 0); | ||
269 | if (curfp && curfp->private_data) { | ||
270 | const struct inode *inode; | ||
271 | dget(curfp->f_dentry); | ||
272 | inode = curfp->f_dentry->d_inode; | ||
273 | if (S_ISCHR(inode->i_mode)) { | ||
274 | struct tty_struct *tty; | ||
275 | tty = (struct tty_struct *)curfp->private_data; | ||
276 | if (tty && tty->magic == TTY_MAGIC) { | ||
277 | tty = tty_pair_get_tty(tty); | ||
278 | current_dev = tty_devnum(tty); | ||
279 | } | ||
280 | } | ||
281 | dput(curfp->f_dentry); | ||
282 | } | ||
283 | spin_unlock(&curfiles->file_lock); | ||
284 | put_files_struct(curfiles); | ||
285 | } | ||
286 | return seq_open(file, &tty_consoles_op); | ||
287 | } | ||
288 | |||
289 | static const struct file_operations proc_tty_consoles_operations = { | ||
290 | .open = tty_consoles_open, | ||
291 | .read = seq_read, | ||
292 | .llseek = seq_lseek, | ||
293 | .release = seq_release, | ||
294 | }; | ||
295 | |||
296 | /* | ||
140 | * This function is called by tty_register_driver() to handle | 297 | * This function is called by tty_register_driver() to handle |
141 | * registering the driver's /proc handler into /proc/tty/driver/<foo> | 298 | * registering the driver's /proc handler into /proc/tty/driver/<foo> |
142 | */ | 299 | */ |
@@ -186,4 +343,5 @@ void __init proc_tty_init(void) | |||
186 | proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL); | 343 | proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL); |
187 | proc_create("tty/ldiscs", 0, NULL, &tty_ldiscs_proc_fops); | 344 | proc_create("tty/ldiscs", 0, NULL, &tty_ldiscs_proc_fops); |
188 | proc_create("tty/drivers", 0, NULL, &proc_tty_drivers_operations); | 345 | proc_create("tty/drivers", 0, NULL, &proc_tty_drivers_operations); |
346 | proc_create("tty/consoles", 0, NULL, &proc_tty_consoles_operations); | ||
189 | } | 347 | } |