aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/pty.c78
-rw-r--r--drivers/char/tty_io.c169
-rw-r--r--drivers/char/tty_ioctl.c66
-rw-r--r--drivers/char/vt.c30
-rw-r--r--include/linux/tty.h6
-rw-r--r--include/linux/vt_kern.h2
6 files changed, 195 insertions, 156 deletions
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index ec09c1cd4fe9..328e8ac12306 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -23,6 +23,7 @@
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/sysctl.h> 25#include <linux/sysctl.h>
26#include <linux/device.h>
26 27
27#include <asm/uaccess.h> 28#include <asm/uaccess.h>
28#include <asm/system.h> 29#include <asm/system.h>
@@ -332,6 +333,8 @@ int pty_limit = NR_UNIX98_PTY_DEFAULT;
332static int pty_limit_min = 0; 333static int pty_limit_min = 0;
333static int pty_limit_max = NR_UNIX98_PTY_MAX; 334static int pty_limit_max = NR_UNIX98_PTY_MAX;
334 335
336static struct cdev ptmx_cdev;
337
335static struct ctl_table pty_table[] = { 338static struct ctl_table pty_table[] = {
336 { 339 {
337 .ctl_name = PTY_MAX, 340 .ctl_name = PTY_MAX,
@@ -408,6 +411,70 @@ static const struct tty_operations ptm_unix98_ops = {
408 .shutdown = pty_shutdown 411 .shutdown = pty_shutdown
409}; 412};
410 413
414
415/**
416 * ptmx_open - open a unix 98 pty master
417 * @inode: inode of device file
418 * @filp: file pointer to tty
419 *
420 * Allocate a unix98 pty master device from the ptmx driver.
421 *
422 * Locking: tty_mutex protects the init_dev work. tty->count should
423 * protect the rest.
424 * allocated_ptys_lock handles the list of free pty numbers
425 */
426
427static int __ptmx_open(struct inode *inode, struct file *filp)
428{
429 struct tty_struct *tty;
430 int retval;
431 int index;
432
433 nonseekable_open(inode, filp);
434
435 /* find a device that is not in use. */
436 index = devpts_new_index();
437 if (index < 0)
438 return index;
439
440 mutex_lock(&tty_mutex);
441 retval = tty_init_dev(ptm_driver, index, &tty, 1);
442 mutex_unlock(&tty_mutex);
443
444 if (retval)
445 goto out;
446
447 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
448 filp->private_data = tty;
449 file_move(filp, &tty->tty_files);
450
451 retval = devpts_pty_new(tty->link);
452 if (retval)
453 goto out1;
454
455 retval = ptm_driver->ops->open(tty, filp);
456 if (!retval)
457 return 0;
458out1:
459 tty_release_dev(filp);
460 return retval;
461out:
462 devpts_kill_index(index);
463 return retval;
464}
465
466static int ptmx_open(struct inode *inode, struct file *filp)
467{
468 int ret;
469
470 lock_kernel();
471 ret = __ptmx_open(inode, filp);
472 unlock_kernel();
473 return ret;
474}
475
476static struct file_operations ptmx_fops;
477
411static void __init unix98_pty_init(void) 478static void __init unix98_pty_init(void)
412{ 479{
413 ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX); 480 ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX);
@@ -459,7 +526,18 @@ static void __init unix98_pty_init(void)
459 526
460 pty_table[1].data = &ptm_driver->refcount; 527 pty_table[1].data = &ptm_driver->refcount;
461 register_sysctl_table(pty_root_table); 528 register_sysctl_table(pty_root_table);
529
530 /* Now create the /dev/ptmx special device */
531 tty_default_fops(&ptmx_fops);
532 ptmx_fops.open = ptmx_open;
533
534 cdev_init(&ptmx_cdev, &ptmx_fops);
535 if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
536 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
537 panic("Couldn't register /dev/ptmx driver\n");
538 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
462} 539}
540
463#else 541#else
464static inline void unix98_pty_init(void) { } 542static inline void unix98_pty_init(void) { }
465#endif 543#endif
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index f91704d57a4e..fdcc43c8ef3c 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -49,7 +49,7 @@
49 * implement CONFIG_VT and generalize console device interface. 49 * implement CONFIG_VT and generalize console device interface.
50 * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97 50 * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97
51 * 51 *
52 * Rewrote init_dev and release_dev to eliminate races. 52 * Rewrote tty_init_dev and tty_release_dev to eliminate races.
53 * -- Bill Hawes <whawes@star.net>, June 97 53 * -- Bill Hawes <whawes@star.net>, June 97
54 * 54 *
55 * Added devfs support. 55 * Added devfs support.
@@ -136,11 +136,6 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */
136DEFINE_MUTEX(tty_mutex); 136DEFINE_MUTEX(tty_mutex);
137EXPORT_SYMBOL(tty_mutex); 137EXPORT_SYMBOL(tty_mutex);
138 138
139#ifdef CONFIG_UNIX98_PTYS
140extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */
141static int ptmx_open(struct inode *, struct file *);
142#endif
143
144static void initialize_tty_struct(struct tty_struct *tty); 139static void initialize_tty_struct(struct tty_struct *tty);
145 140
146static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); 141static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
@@ -425,20 +420,6 @@ static const struct file_operations tty_fops = {
425 .fasync = tty_fasync, 420 .fasync = tty_fasync,
426}; 421};
427 422
428#ifdef CONFIG_UNIX98_PTYS
429static const struct file_operations ptmx_fops = {
430 .llseek = no_llseek,
431 .read = tty_read,
432 .write = tty_write,
433 .poll = tty_poll,
434 .unlocked_ioctl = tty_ioctl,
435 .compat_ioctl = tty_compat_ioctl,
436 .open = ptmx_open,
437 .release = tty_release,
438 .fasync = tty_fasync,
439};
440#endif
441
442static const struct file_operations console_fops = { 423static const struct file_operations console_fops = {
443 .llseek = no_llseek, 424 .llseek = no_llseek,
444 .read = tty_read, 425 .read = tty_read,
@@ -1224,7 +1205,7 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p)
1224} 1205}
1225 1206
1226/** 1207/**
1227 * init_dev - initialise a tty device 1208 * tty_init_dev - initialise a tty device
1228 * @driver: tty driver we are opening a device on 1209 * @driver: tty driver we are opening a device on
1229 * @idx: device index 1210 * @idx: device index
1230 * @ret_tty: returned tty structure 1211 * @ret_tty: returned tty structure
@@ -1248,7 +1229,7 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p)
1248 * relaxed for the (most common) case of reopening a tty. 1229 * relaxed for the (most common) case of reopening a tty.
1249 */ 1230 */
1250 1231
1251static int init_dev(struct tty_driver *driver, int idx, 1232int tty_init_dev(struct tty_driver *driver, int idx,
1252 struct tty_struct **ret_tty, int first_ok) 1233 struct tty_struct **ret_tty, int first_ok)
1253{ 1234{
1254 struct tty_struct *tty, *o_tty; 1235 struct tty_struct *tty, *o_tty;
@@ -1269,8 +1250,8 @@ static int init_dev(struct tty_driver *driver, int idx,
1269 goto end_init; 1250 goto end_init;
1270 } 1251 }
1271 /* 1252 /*
1272 * It's safe from now on because init_dev() is called with 1253 * It's safe from now on because tty_init_dev() is called with
1273 * tty_mutex held and release_dev() won't change tty->count 1254 * tty_mutex held and tty_release_dev() won't change tty->count
1274 * or tty->flags without having to grab tty_mutex 1255 * or tty->flags without having to grab tty_mutex
1275 */ 1256 */
1276 if (tty && driver->subtype == PTY_TYPE_MASTER) 1257 if (tty && driver->subtype == PTY_TYPE_MASTER)
@@ -1449,7 +1430,7 @@ fast_track:
1449 1430
1450 /* FIXME */ 1431 /* FIXME */
1451 if (!test_bit(TTY_LDISC, &tty->flags)) 1432 if (!test_bit(TTY_LDISC, &tty->flags))
1452 printk(KERN_ERR "init_dev but no ldisc\n"); 1433 printk(KERN_ERR "tty_init_dev but no ldisc\n");
1453success: 1434success:
1454 *ret_tty = tty; 1435 *ret_tty = tty;
1455 1436
@@ -1476,7 +1457,7 @@ fail_no_mem:
1476 /* call the tty release_tty routine to clean out this slot */ 1457 /* call the tty release_tty routine to clean out this slot */
1477release_mem_out: 1458release_mem_out:
1478 if (printk_ratelimit()) 1459 if (printk_ratelimit())
1479 printk(KERN_INFO "init_dev: ldisc open failed, " 1460 printk(KERN_INFO "tty_init_dev: ldisc open failed, "
1480 "clearing slot %d\n", idx); 1461 "clearing slot %d\n", idx);
1481 release_tty(tty, idx); 1462 release_tty(tty, idx);
1482 goto end_init; 1463 goto end_init;
@@ -1587,7 +1568,7 @@ static void release_tty(struct tty_struct *tty, int idx)
1587 * WSH 09/09/97: rewritten to avoid some nasty race conditions that could 1568 * WSH 09/09/97: rewritten to avoid some nasty race conditions that could
1588 * lead to double frees or releasing memory still in use. 1569 * lead to double frees or releasing memory still in use.
1589 */ 1570 */
1590static void release_dev(struct file *filp) 1571void tty_release_dev(struct file *filp)
1591{ 1572{
1592 struct tty_struct *tty, *o_tty; 1573 struct tty_struct *tty, *o_tty;
1593 int pty_master, tty_closing, o_tty_closing, do_sleep; 1574 int pty_master, tty_closing, o_tty_closing, do_sleep;
@@ -1597,10 +1578,10 @@ static void release_dev(struct file *filp)
1597 1578
1598 tty = (struct tty_struct *)filp->private_data; 1579 tty = (struct tty_struct *)filp->private_data;
1599 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, 1580 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode,
1600 "release_dev")) 1581 "tty_release_dev"))
1601 return; 1582 return;
1602 1583
1603 check_tty_count(tty, "release_dev"); 1584 check_tty_count(tty, "tty_release_dev");
1604 1585
1605 tty_fasync(-1, filp, 0); 1586 tty_fasync(-1, filp, 0);
1606 1587
@@ -1612,24 +1593,24 @@ static void release_dev(struct file *filp)
1612 1593
1613#ifdef TTY_PARANOIA_CHECK 1594#ifdef TTY_PARANOIA_CHECK
1614 if (idx < 0 || idx >= tty->driver->num) { 1595 if (idx < 0 || idx >= tty->driver->num) {
1615 printk(KERN_DEBUG "release_dev: bad idx when trying to " 1596 printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
1616 "free (%s)\n", tty->name); 1597 "free (%s)\n", tty->name);
1617 return; 1598 return;
1618 } 1599 }
1619 if (!(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { 1600 if (!(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
1620 if (tty != tty->driver->ttys[idx]) { 1601 if (tty != tty->driver->ttys[idx]) {
1621 printk(KERN_DEBUG "release_dev: driver.table[%d] not tty " 1602 printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
1622 "for (%s)\n", idx, tty->name); 1603 "for (%s)\n", idx, tty->name);
1623 return; 1604 return;
1624 } 1605 }
1625 if (tty->termios != tty->driver->termios[idx]) { 1606 if (tty->termios != tty->driver->termios[idx]) {
1626 printk(KERN_DEBUG "release_dev: driver.termios[%d] not termios " 1607 printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
1627 "for (%s)\n", 1608 "for (%s)\n",
1628 idx, tty->name); 1609 idx, tty->name);
1629 return; 1610 return;
1630 } 1611 }
1631 if (tty->termios_locked != tty->driver->termios_locked[idx]) { 1612 if (tty->termios_locked != tty->driver->termios_locked[idx]) {
1632 printk(KERN_DEBUG "release_dev: driver.termios_locked[%d] not " 1613 printk(KERN_DEBUG "tty_release_dev: driver.termios_locked[%d] not "
1633 "termios_locked for (%s)\n", 1614 "termios_locked for (%s)\n",
1634 idx, tty->name); 1615 idx, tty->name);
1635 return; 1616 return;
@@ -1638,7 +1619,7 @@ static void release_dev(struct file *filp)
1638#endif 1619#endif
1639 1620
1640#ifdef TTY_DEBUG_HANGUP 1621#ifdef TTY_DEBUG_HANGUP
1641 printk(KERN_DEBUG "release_dev of %s (tty count=%d)...", 1622 printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...",
1642 tty_name(tty, buf), tty->count); 1623 tty_name(tty, buf), tty->count);
1643#endif 1624#endif
1644 1625
@@ -1646,26 +1627,26 @@ static void release_dev(struct file *filp)
1646 if (tty->driver->other && 1627 if (tty->driver->other &&
1647 !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { 1628 !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
1648 if (o_tty != tty->driver->other->ttys[idx]) { 1629 if (o_tty != tty->driver->other->ttys[idx]) {
1649 printk(KERN_DEBUG "release_dev: other->table[%d] " 1630 printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
1650 "not o_tty for (%s)\n", 1631 "not o_tty for (%s)\n",
1651 idx, tty->name); 1632 idx, tty->name);
1652 return; 1633 return;
1653 } 1634 }
1654 if (o_tty->termios != tty->driver->other->termios[idx]) { 1635 if (o_tty->termios != tty->driver->other->termios[idx]) {
1655 printk(KERN_DEBUG "release_dev: other->termios[%d] " 1636 printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
1656 "not o_termios for (%s)\n", 1637 "not o_termios for (%s)\n",
1657 idx, tty->name); 1638 idx, tty->name);
1658 return; 1639 return;
1659 } 1640 }
1660 if (o_tty->termios_locked != 1641 if (o_tty->termios_locked !=
1661 tty->driver->other->termios_locked[idx]) { 1642 tty->driver->other->termios_locked[idx]) {
1662 printk(KERN_DEBUG "release_dev: other->termios_locked[" 1643 printk(KERN_DEBUG "tty_release_dev: other->termios_locked["
1663 "%d] not o_termios_locked for (%s)\n", 1644 "%d] not o_termios_locked for (%s)\n",
1664 idx, tty->name); 1645 idx, tty->name);
1665 return; 1646 return;
1666 } 1647 }
1667 if (o_tty->link != tty) { 1648 if (o_tty->link != tty) {
1668 printk(KERN_DEBUG "release_dev: bad pty pointers\n"); 1649 printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
1669 return; 1650 return;
1670 } 1651 }
1671 } 1652 }
@@ -1723,7 +1704,7 @@ static void release_dev(struct file *filp)
1723 if (!do_sleep) 1704 if (!do_sleep)
1724 break; 1705 break;
1725 1706
1726 printk(KERN_WARNING "release_dev: %s: read/write wait queue " 1707 printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue "
1727 "active!\n", tty_name(tty, buf)); 1708 "active!\n", tty_name(tty, buf));
1728 mutex_unlock(&tty_mutex); 1709 mutex_unlock(&tty_mutex);
1729 schedule(); 1710 schedule();
@@ -1736,14 +1717,14 @@ static void release_dev(struct file *filp)
1736 */ 1717 */
1737 if (pty_master) { 1718 if (pty_master) {
1738 if (--o_tty->count < 0) { 1719 if (--o_tty->count < 0) {
1739 printk(KERN_WARNING "release_dev: bad pty slave count " 1720 printk(KERN_WARNING "tty_release_dev: bad pty slave count "
1740 "(%d) for %s\n", 1721 "(%d) for %s\n",
1741 o_tty->count, tty_name(o_tty, buf)); 1722 o_tty->count, tty_name(o_tty, buf));
1742 o_tty->count = 0; 1723 o_tty->count = 0;
1743 } 1724 }
1744 } 1725 }
1745 if (--tty->count < 0) { 1726 if (--tty->count < 0) {
1746 printk(KERN_WARNING "release_dev: bad tty->count (%d) for %s\n", 1727 printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n",
1747 tty->count, tty_name(tty, buf)); 1728 tty->count, tty_name(tty, buf));
1748 tty->count = 0; 1729 tty->count = 0;
1749 } 1730 }
@@ -1825,7 +1806,7 @@ static void release_dev(struct file *filp)
1825 * The termios state of a pty is reset on first open so that 1806 * The termios state of a pty is reset on first open so that
1826 * settings don't persist across reuse. 1807 * settings don't persist across reuse.
1827 * 1808 *
1828 * Locking: tty_mutex protects tty, get_tty_driver and init_dev work. 1809 * Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work.
1829 * tty->count should protect the rest. 1810 * tty->count should protect the rest.
1830 * ->siglock protects ->signal/->sighand 1811 * ->siglock protects ->signal/->sighand
1831 */ 1812 */
@@ -1889,7 +1870,7 @@ retry_open:
1889 return -ENODEV; 1870 return -ENODEV;
1890 } 1871 }
1891got_driver: 1872got_driver:
1892 retval = init_dev(driver, index, &tty, 0); 1873 retval = tty_init_dev(driver, index, &tty, 0);
1893 mutex_unlock(&tty_mutex); 1874 mutex_unlock(&tty_mutex);
1894 if (retval) 1875 if (retval)
1895 return retval; 1876 return retval;
@@ -1920,7 +1901,7 @@ got_driver:
1920 printk(KERN_DEBUG "error %d in opening %s...", retval, 1901 printk(KERN_DEBUG "error %d in opening %s...", retval,
1921 tty->name); 1902 tty->name);
1922#endif 1903#endif
1923 release_dev(filp); 1904 tty_release_dev(filp);
1924 if (retval != -ERESTARTSYS) 1905 if (retval != -ERESTARTSYS)
1925 return retval; 1906 return retval;
1926 if (signal_pending(current)) 1907 if (signal_pending(current))
@@ -1959,69 +1940,6 @@ static int tty_open(struct inode *inode, struct file *filp)
1959 1940
1960 1941
1961 1942
1962#ifdef CONFIG_UNIX98_PTYS
1963/**
1964 * ptmx_open - open a unix 98 pty master
1965 * @inode: inode of device file
1966 * @filp: file pointer to tty
1967 *
1968 * Allocate a unix98 pty master device from the ptmx driver.
1969 *
1970 * Locking: tty_mutex protects theinit_dev work. tty->count should
1971 * protect the rest.
1972 * allocated_ptys_lock handles the list of free pty numbers
1973 */
1974
1975static int __ptmx_open(struct inode *inode, struct file *filp)
1976{
1977 struct tty_struct *tty;
1978 int retval;
1979 int index;
1980
1981 nonseekable_open(inode, filp);
1982
1983 /* find a device that is not in use. */
1984 index = devpts_new_index();
1985 if (index < 0)
1986 return index;
1987
1988 mutex_lock(&tty_mutex);
1989 retval = init_dev(ptm_driver, index, &tty, 1);
1990 mutex_unlock(&tty_mutex);
1991
1992 if (retval)
1993 goto out;
1994
1995 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
1996 filp->private_data = tty;
1997 file_move(filp, &tty->tty_files);
1998
1999 retval = devpts_pty_new(tty->link);
2000 if (retval)
2001 goto out1;
2002
2003 check_tty_count(tty, "ptmx_open");
2004 retval = ptm_driver->ops->open(tty, filp);
2005 if (!retval)
2006 return 0;
2007out1:
2008 release_dev(filp);
2009 return retval;
2010out:
2011 devpts_kill_index(index);
2012 return retval;
2013}
2014
2015static int ptmx_open(struct inode *inode, struct file *filp)
2016{
2017 int ret;
2018
2019 lock_kernel();
2020 ret = __ptmx_open(inode, filp);
2021 unlock_kernel();
2022 return ret;
2023}
2024#endif
2025 1943
2026/** 1944/**
2027 * tty_release - vfs callback for close 1945 * tty_release - vfs callback for close
@@ -2032,13 +1950,13 @@ static int ptmx_open(struct inode *inode, struct file *filp)
2032 * this tty. There may however be several such references. 1950 * this tty. There may however be several such references.
2033 * 1951 *
2034 * Locking: 1952 * Locking:
2035 * Takes bkl. See release_dev 1953 * Takes bkl. See tty_release_dev
2036 */ 1954 */
2037 1955
2038static int tty_release(struct inode *inode, struct file *filp) 1956static int tty_release(struct inode *inode, struct file *filp)
2039{ 1957{
2040 lock_kernel(); 1958 lock_kernel();
2041 release_dev(filp); 1959 tty_release_dev(filp);
2042 unlock_kernel(); 1960 unlock_kernel();
2043 return 0; 1961 return 0;
2044} 1962}
@@ -2932,7 +2850,7 @@ int tty_put_char(struct tty_struct *tty, unsigned char ch)
2932 2850
2933EXPORT_SYMBOL_GPL(tty_put_char); 2851EXPORT_SYMBOL_GPL(tty_put_char);
2934 2852
2935static struct class *tty_class; 2853struct class *tty_class;
2936 2854
2937/** 2855/**
2938 * tty_register_device - register a tty device 2856 * tty_register_device - register a tty device
@@ -3197,6 +3115,11 @@ struct tty_struct *get_current_tty(void)
3197} 3115}
3198EXPORT_SYMBOL_GPL(get_current_tty); 3116EXPORT_SYMBOL_GPL(get_current_tty);
3199 3117
3118void tty_default_fops(struct file_operations *fops)
3119{
3120 *fops = tty_fops;
3121}
3122
3200/* 3123/*
3201 * Initialize the console device. This is called *early*, so 3124 * Initialize the console device. This is called *early*, so
3202 * we can't necessarily depend on lots of kernel help here. 3125 * we can't necessarily depend on lots of kernel help here.
@@ -3234,12 +3157,6 @@ postcore_initcall(tty_class_init);
3234/* 3/2004 jmc: why do these devices exist? */ 3157/* 3/2004 jmc: why do these devices exist? */
3235 3158
3236static struct cdev tty_cdev, console_cdev; 3159static struct cdev tty_cdev, console_cdev;
3237#ifdef CONFIG_UNIX98_PTYS
3238static struct cdev ptmx_cdev;
3239#endif
3240#ifdef CONFIG_VT
3241static struct cdev vc0_cdev;
3242#endif
3243 3160
3244/* 3161/*
3245 * Ok, now we can initialize the rest of the tty devices and can count 3162 * Ok, now we can initialize the rest of the tty devices and can count
@@ -3251,32 +3168,18 @@ static int __init tty_init(void)
3251 if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || 3168 if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
3252 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) 3169 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
3253 panic("Couldn't register /dev/tty driver\n"); 3170 panic("Couldn't register /dev/tty driver\n");
3254 device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, 3171 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,
3255 "tty"); 3172 "tty");
3256 3173
3257 cdev_init(&console_cdev, &console_fops); 3174 cdev_init(&console_cdev, &console_fops);
3258 if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || 3175 if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
3259 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) 3176 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
3260 panic("Couldn't register /dev/console driver\n"); 3177 panic("Couldn't register /dev/console driver\n");
3261 device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, 3178 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
3262 "console"); 3179 "console");
3263 3180
3264#ifdef CONFIG_UNIX98_PTYS
3265 cdev_init(&ptmx_cdev, &ptmx_fops);
3266 if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
3267 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
3268 panic("Couldn't register /dev/ptmx driver\n");
3269 device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
3270#endif
3271
3272#ifdef CONFIG_VT 3181#ifdef CONFIG_VT
3273 cdev_init(&vc0_cdev, &console_fops); 3182 vty_init(&console_fops);
3274 if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
3275 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
3276 panic("Couldn't register /dev/tty0 driver\n");
3277 device_create_drvdata(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
3278
3279 vty_init();
3280#endif 3183#endif
3281 return 0; 3184 return 0;
3282} 3185}
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 30670851e51a..14cc19c344cc 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -40,6 +40,15 @@
40#define TERMIOS_OLD 8 40#define TERMIOS_OLD 8
41 41
42 42
43/**
44 * tty_chars_in_buffer - characters pending
45 * @tty: terminal
46 *
47 * Return the number of bytes of data in the device private
48 * output queue. If no private method is supplied there is assumed
49 * to be no queue on the device.
50 */
51
43int tty_chars_in_buffer(struct tty_struct *tty) 52int tty_chars_in_buffer(struct tty_struct *tty)
44{ 53{
45 if (tty->ops->chars_in_buffer) 54 if (tty->ops->chars_in_buffer)
@@ -47,26 +56,49 @@ int tty_chars_in_buffer(struct tty_struct *tty)
47 else 56 else
48 return 0; 57 return 0;
49} 58}
50
51EXPORT_SYMBOL(tty_chars_in_buffer); 59EXPORT_SYMBOL(tty_chars_in_buffer);
52 60
61/**
62 * tty_write_room - write queue space
63 * @tty: terminal
64 *
65 * Return the number of bytes that can be queued to this device
66 * at the present time. The result should be treated as a guarantee
67 * and the driver cannot offer a value it later shrinks by more than
68 * the number of bytes written. If no method is provided 2K is always
69 * returned and data may be lost as there will be no flow control.
70 */
71
53int tty_write_room(struct tty_struct *tty) 72int tty_write_room(struct tty_struct *tty)
54{ 73{
55 if (tty->ops->write_room) 74 if (tty->ops->write_room)
56 return tty->ops->write_room(tty); 75 return tty->ops->write_room(tty);
57 return 2048; 76 return 2048;
58} 77}
59
60EXPORT_SYMBOL(tty_write_room); 78EXPORT_SYMBOL(tty_write_room);
61 79
80/**
81 * tty_driver_flush_buffer - discard internal buffer
82 * @tty: terminal
83 *
84 * Discard the internal output buffer for this device. If no method
85 * is provided then either the buffer cannot be hardware flushed or
86 * there is no buffer driver side.
87 */
62void tty_driver_flush_buffer(struct tty_struct *tty) 88void tty_driver_flush_buffer(struct tty_struct *tty)
63{ 89{
64 if (tty->ops->flush_buffer) 90 if (tty->ops->flush_buffer)
65 tty->ops->flush_buffer(tty); 91 tty->ops->flush_buffer(tty);
66} 92}
67
68EXPORT_SYMBOL(tty_driver_flush_buffer); 93EXPORT_SYMBOL(tty_driver_flush_buffer);
69 94
95/**
96 * tty_throttle - flow control
97 * @tty: terminal
98 *
99 * Indicate that a tty should stop transmitting data down the stack.
100 */
101
70void tty_throttle(struct tty_struct *tty) 102void tty_throttle(struct tty_struct *tty)
71{ 103{
72 /* check TTY_THROTTLED first so it indicates our state */ 104 /* check TTY_THROTTLED first so it indicates our state */
@@ -76,6 +108,13 @@ void tty_throttle(struct tty_struct *tty)
76} 108}
77EXPORT_SYMBOL(tty_throttle); 109EXPORT_SYMBOL(tty_throttle);
78 110
111/**
112 * tty_unthrottle - flow control
113 * @tty: terminal
114 *
115 * Indicate that a tty may continue transmitting data down the stack.
116 */
117
79void tty_unthrottle(struct tty_struct *tty) 118void tty_unthrottle(struct tty_struct *tty)
80{ 119{
81 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && 120 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
@@ -112,6 +151,11 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout)
112} 151}
113EXPORT_SYMBOL(tty_wait_until_sent); 152EXPORT_SYMBOL(tty_wait_until_sent);
114 153
154
155/*
156 * Termios Helper Methods
157 */
158
115static void unset_locked_termios(struct ktermios *termios, 159static void unset_locked_termios(struct ktermios *termios,
116 struct ktermios *old, 160 struct ktermios *old,
117 struct ktermios *locked) 161 struct ktermios *locked)
@@ -346,6 +390,16 @@ void tty_termios_encode_baud_rate(struct ktermios *termios,
346} 390}
347EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); 391EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
348 392
393/**
394 * tty_encode_baud_rate - set baud rate of the tty
395 * @ibaud: input baud rate
396 * @obad: output baud rate
397 *
398 * Update the current termios data for the tty with the new speed
399 * settings. The caller must hold the termios_mutex for the tty in
400 * question.
401 */
402
349void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) 403void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
350{ 404{
351 tty_termios_encode_baud_rate(tty->termios, ibaud, obaud); 405 tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
@@ -430,7 +484,7 @@ EXPORT_SYMBOL(tty_termios_hw_change);
430 * is a bit of layering violation here with n_tty in terms of the 484 * is a bit of layering violation here with n_tty in terms of the
431 * internal knowledge of this function. 485 * internal knowledge of this function.
432 * 486 *
433 * Locking: termios_sem 487 * Locking: termios_mutex
434 */ 488 */
435 489
436static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) 490static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
@@ -508,7 +562,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
508 * functions before using change_termios to do the actual changes. 562 * functions before using change_termios to do the actual changes.
509 * 563 *
510 * Locking: 564 * Locking:
511 * Called functions take ldisc and termios_sem locks 565 * Called functions take ldisc and termios_mutex locks
512 */ 566 */
513 567
514static int set_termios(struct tty_struct *tty, void __user *arg, int opt) 568static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
@@ -715,7 +769,7 @@ static void set_sgflags(struct ktermios *termios, int flags)
715 * Updates a terminal from the legacy BSD style terminal information 769 * Updates a terminal from the legacy BSD style terminal information
716 * structure. 770 * structure.
717 * 771 *
718 * Locking: termios_sem 772 * Locking: termios_mutex
719 */ 773 */
720 774
721static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) 775static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 37a45db5bae0..57029fefd64a 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -100,10 +100,10 @@
100#include <linux/font.h> 100#include <linux/font.h>
101#include <linux/bitops.h> 101#include <linux/bitops.h>
102#include <linux/notifier.h> 102#include <linux/notifier.h>
103 103#include <linux/device.h>
104#include <asm/io.h> 104#include <linux/io.h>
105#include <asm/system.h> 105#include <asm/system.h>
106#include <asm/uaccess.h> 106#include <linux/uaccess.h>
107 107
108#define MAX_NR_CON_DRIVER 16 108#define MAX_NR_CON_DRIVER 16
109 109
@@ -2352,8 +2352,6 @@ rescan_last_byte:
2352 FLUSH 2352 FLUSH
2353 console_conditional_schedule(); 2353 console_conditional_schedule();
2354 release_console_sem(); 2354 release_console_sem();
2355
2356out:
2357 notify_update(vc); 2355 notify_update(vc);
2358 return n; 2356 return n;
2359#undef FLUSH 2357#undef FLUSH
@@ -2784,13 +2782,6 @@ static int con_open(struct tty_struct *tty, struct file *filp)
2784 return ret; 2782 return ret;
2785} 2783}
2786 2784
2787/*
2788 * We take tty_mutex in here to prevent another thread from coming in via init_dev
2789 * and taking a ref against the tty while we're in the process of forgetting
2790 * about it and cleaning things up.
2791 *
2792 * This is because vcs_remove_sysfs() can sleep and will drop the BKL.
2793 */
2794static void con_close(struct tty_struct *tty, struct file *filp) 2785static void con_close(struct tty_struct *tty, struct file *filp)
2795{ 2786{
2796 /* Nothing to do - we defer to shutdown */ 2787 /* Nothing to do - we defer to shutdown */
@@ -2932,8 +2923,16 @@ static const struct tty_operations con_ops = {
2932 .shutdown = con_shutdown 2923 .shutdown = con_shutdown
2933}; 2924};
2934 2925
2935int __init vty_init(void) 2926static struct cdev vc0_cdev;
2927
2928int __init vty_init(const struct file_operations *console_fops)
2936{ 2929{
2930 cdev_init(&vc0_cdev, console_fops);
2931 if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
2932 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
2933 panic("Couldn't register /dev/tty0 driver\n");
2934 device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
2935
2937 vcs_init(); 2936 vcs_init();
2938 2937
2939 console_driver = alloc_tty_driver(MAX_NR_CONSOLES); 2938 console_driver = alloc_tty_driver(MAX_NR_CONSOLES);
@@ -2952,7 +2951,6 @@ int __init vty_init(void)
2952 tty_set_operations(console_driver, &con_ops); 2951 tty_set_operations(console_driver, &con_ops);
2953 if (tty_register_driver(console_driver)) 2952 if (tty_register_driver(console_driver))
2954 panic("Couldn't register console driver\n"); 2953 panic("Couldn't register console driver\n");
2955
2956 kbd_init(); 2954 kbd_init();
2957 console_map_init(); 2955 console_map_init();
2958#ifdef CONFIG_PROM_CONSOLE 2956#ifdef CONFIG_PROM_CONSOLE
@@ -3446,7 +3444,7 @@ int register_con_driver(const struct consw *csw, int first, int last)
3446 if (retval) 3444 if (retval)
3447 goto err; 3445 goto err;
3448 3446
3449 con_driver->dev = device_create_drvdata(vtconsole_class, NULL, 3447 con_driver->dev = device_create(vtconsole_class, NULL,
3450 MKDEV(0, con_driver->node), 3448 MKDEV(0, con_driver->node),
3451 NULL, "vtcon%i", 3449 NULL, "vtcon%i",
3452 con_driver->node); 3450 con_driver->node);
@@ -3557,7 +3555,7 @@ static int __init vtconsole_class_init(void)
3557 struct con_driver *con = &registered_con_driver[i]; 3555 struct con_driver *con = &registered_con_driver[i];
3558 3556
3559 if (con->con && !con->dev) { 3557 if (con->con && !con->dev) {
3560 con->dev = device_create_drvdata(vtconsole_class, NULL, 3558 con->dev = device_create(vtconsole_class, NULL,
3561 MKDEV(0, con->node), 3559 MKDEV(0, con->node),
3562 NULL, "vtcon%i", 3560 NULL, "vtcon%i",
3563 con->node); 3561 con->node);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 6e39c705b9b6..6cc7ccc93c69 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -314,6 +314,8 @@ extern int kmsg_redirect;
314extern void console_init(void); 314extern void console_init(void);
315extern int vcs_init(void); 315extern int vcs_init(void);
316 316
317extern struct class *tty_class;
318
317/** 319/**
318 * tty_kref_get - get a tty reference 320 * tty_kref_get - get a tty reference
319 * @tty: tty device 321 * @tty: tty device
@@ -398,6 +400,10 @@ extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg);
398extern dev_t tty_devnum(struct tty_struct *tty); 400extern dev_t tty_devnum(struct tty_struct *tty);
399extern void proc_clear_tty(struct task_struct *p); 401extern void proc_clear_tty(struct task_struct *p);
400extern struct tty_struct *get_current_tty(void); 402extern struct tty_struct *get_current_tty(void);
403extern void tty_default_fops(struct file_operations *fops);
404extern int tty_init_dev(struct tty_driver *driver, int idx,
405 struct tty_struct **ret_tty, int first_ok);
406extern void tty_release_dev(struct file *filp);
401 407
402extern struct mutex tty_mutex; 408extern struct mutex tty_mutex;
403 409
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 1cbd0a7db4e6..2f1113467f70 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -96,7 +96,7 @@ void change_console(struct vc_data *new_vc);
96void reset_vc(struct vc_data *vc); 96void reset_vc(struct vc_data *vc);
97extern int unbind_con_driver(const struct consw *csw, int first, int last, 97extern int unbind_con_driver(const struct consw *csw, int first, int last,
98 int deflt); 98 int deflt);
99int vty_init(void); 99int vty_init(const struct file_operations *console_fops);
100 100
101/* 101/*
102 * vc_screen.c shares this temporary buffer with the console write code so that 102 * vc_screen.c shares this temporary buffer with the console write code so that