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/proc_tty.c | |
| 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/proc_tty.c')
| -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 | } |
