diff options
author | Alan Cox <alan@redhat.com> | 2008-10-13 05:41:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 12:51:42 -0400 |
commit | d81ed10307027e1643a65ab5fe17cc01233d376d (patch) | |
tree | e46ac5735124308357f42214a8a26f75dcd3f412 /drivers | |
parent | feebed6515a113eeb33919e9557a8b9710ea627c (diff) |
tty: Remove more special casing and out of place code
Carry on pushing code out of tty_io when it belongs to other drivers. I'm
not 100% happy with some of this and it will be worth revisiting some of the
exports later when the restructuring work is done.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/pty.c | 78 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 169 | ||||
-rw-r--r-- | drivers/char/tty_ioctl.c | 66 | ||||
-rw-r--r-- | drivers/char/vt.c | 30 |
4 files changed, 188 insertions, 155 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; | |||
332 | static int pty_limit_min = 0; | 333 | static int pty_limit_min = 0; |
333 | static int pty_limit_max = NR_UNIX98_PTY_MAX; | 334 | static int pty_limit_max = NR_UNIX98_PTY_MAX; |
334 | 335 | ||
336 | static struct cdev ptmx_cdev; | ||
337 | |||
335 | static struct ctl_table pty_table[] = { | 338 | static 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 | |||
427 | static 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; | ||
458 | out1: | ||
459 | tty_release_dev(filp); | ||
460 | return retval; | ||
461 | out: | ||
462 | devpts_kill_index(index); | ||
463 | return retval; | ||
464 | } | ||
465 | |||
466 | static 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 | |||
476 | static struct file_operations ptmx_fops; | ||
477 | |||
411 | static void __init unix98_pty_init(void) | 478 | static 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 |
464 | static inline void unix98_pty_init(void) { } | 542 | static 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 */ | |||
136 | DEFINE_MUTEX(tty_mutex); | 136 | DEFINE_MUTEX(tty_mutex); |
137 | EXPORT_SYMBOL(tty_mutex); | 137 | EXPORT_SYMBOL(tty_mutex); |
138 | 138 | ||
139 | #ifdef CONFIG_UNIX98_PTYS | ||
140 | extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ | ||
141 | static int ptmx_open(struct inode *, struct file *); | ||
142 | #endif | ||
143 | |||
144 | static void initialize_tty_struct(struct tty_struct *tty); | 139 | static void initialize_tty_struct(struct tty_struct *tty); |
145 | 140 | ||
146 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); | 141 | static 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 | ||
429 | static 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 | |||
442 | static const struct file_operations console_fops = { | 423 | static 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 | ||
1251 | static int init_dev(struct tty_driver *driver, int idx, | 1232 | int 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"); |
1453 | success: | 1434 | success: |
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 */ |
1477 | release_mem_out: | 1458 | release_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 | */ |
1590 | static void release_dev(struct file *filp) | 1571 | void 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 | } |
1891 | got_driver: | 1872 | got_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 | |||
1975 | static 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; | ||
2007 | out1: | ||
2008 | release_dev(filp); | ||
2009 | return retval; | ||
2010 | out: | ||
2011 | devpts_kill_index(index); | ||
2012 | return retval; | ||
2013 | } | ||
2014 | |||
2015 | static 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 | ||
2038 | static int tty_release(struct inode *inode, struct file *filp) | 1956 | static 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 | ||
2933 | EXPORT_SYMBOL_GPL(tty_put_char); | 2851 | EXPORT_SYMBOL_GPL(tty_put_char); |
2934 | 2852 | ||
2935 | static struct class *tty_class; | 2853 | struct 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 | } |
3198 | EXPORT_SYMBOL_GPL(get_current_tty); | 3116 | EXPORT_SYMBOL_GPL(get_current_tty); |
3199 | 3117 | ||
3118 | void 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 | ||
3236 | static struct cdev tty_cdev, console_cdev; | 3159 | static struct cdev tty_cdev, console_cdev; |
3237 | #ifdef CONFIG_UNIX98_PTYS | ||
3238 | static struct cdev ptmx_cdev; | ||
3239 | #endif | ||
3240 | #ifdef CONFIG_VT | ||
3241 | static 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 | |||
43 | int tty_chars_in_buffer(struct tty_struct *tty) | 52 | int 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 | |||
51 | EXPORT_SYMBOL(tty_chars_in_buffer); | 59 | EXPORT_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 | |||
53 | int tty_write_room(struct tty_struct *tty) | 72 | int 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 | |||
60 | EXPORT_SYMBOL(tty_write_room); | 78 | EXPORT_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 | */ | ||
62 | void tty_driver_flush_buffer(struct tty_struct *tty) | 88 | void 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 | |||
68 | EXPORT_SYMBOL(tty_driver_flush_buffer); | 93 | EXPORT_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 | |||
70 | void tty_throttle(struct tty_struct *tty) | 102 | void 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 | } |
77 | EXPORT_SYMBOL(tty_throttle); | 109 | EXPORT_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 | |||
79 | void tty_unthrottle(struct tty_struct *tty) | 118 | void 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 | } |
113 | EXPORT_SYMBOL(tty_wait_until_sent); | 152 | EXPORT_SYMBOL(tty_wait_until_sent); |
114 | 153 | ||
154 | |||
155 | /* | ||
156 | * Termios Helper Methods | ||
157 | */ | ||
158 | |||
115 | static void unset_locked_termios(struct ktermios *termios, | 159 | static 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 | } |
347 | EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); | 391 | EXPORT_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 | |||
349 | void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) | 403 | void 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 | ||
436 | static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | 490 | static 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 | ||
514 | static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | 568 | static 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 | ||
721 | static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) | 775 | static 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 | |||
2356 | out: | ||
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 | */ | ||
2794 | static void con_close(struct tty_struct *tty, struct file *filp) | 2785 | static 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 | ||
2935 | int __init vty_init(void) | 2926 | static struct cdev vc0_cdev; |
2927 | |||
2928 | int __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 = ®istered_con_driver[i]; | 3555 | struct con_driver *con = ®istered_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); |