diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 15:09:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 15:09:24 -0500 |
commit | 5983faf942f260023e547f3c5f38c1033c35cc9b (patch) | |
tree | f54ce89de5d9f7a05e99948937ac5456df09df30 /drivers/tty/tty_io.c | |
parent | 21a2cb565a74bf794d343ce22300c5f6c1568ae1 (diff) | |
parent | 995234da19b927f42722d796e8270384f33be11c (diff) |
Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (65 commits)
tty: serial: imx: move del_timer_sync() to avoid potential deadlock
imx: add polled io uart methods
imx: Add save/restore functions for UART control regs
serial/imx: let probing fail for the dt case without a valid alias
serial/imx: propagate error from of_alias_get_id instead of using -ENODEV
tty: serial: imx: Allow UART to be a source for wakeup
serial: driver for m32 arch should not have DEC alpha errata
serial/documentation: fix documented name of DCD cpp symbol
atmel_serial: fix spinlock lockup in RS485 code
tty: Fix memory leak in virtual console when enable unicode translation
serial: use DIV_ROUND_CLOSEST instead of open coding it
serial: add support for 400 and 800 v3 series Titan cards
serial: bfin-uart: Remove ASYNC_CTS_FLOW flag for hardware automatic CTS.
serial: bfin-uart: Enable hardware automatic CTS only when CTS pin is available.
serial: make FSL errata depend on 8250_CONSOLE, not just 8250
serial: add irq handler for Freescale 16550 errata.
serial: manually inline serial8250_handle_port
serial: make 8250 timeout use the specified IRQ handler
serial: export the key functions for an 8250 IRQ handler
serial: clean up parameter passing for 8250 Rx IRQ handling
...
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 309 |
1 files changed, 180 insertions, 129 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3fdebd306b94..e41b9bbc107d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -790,19 +790,24 @@ static void session_clear_tty(struct pid *session) | |||
790 | void disassociate_ctty(int on_exit) | 790 | void disassociate_ctty(int on_exit) |
791 | { | 791 | { |
792 | struct tty_struct *tty; | 792 | struct tty_struct *tty; |
793 | struct pid *tty_pgrp = NULL; | ||
794 | 793 | ||
795 | if (!current->signal->leader) | 794 | if (!current->signal->leader) |
796 | return; | 795 | return; |
797 | 796 | ||
798 | tty = get_current_tty(); | 797 | tty = get_current_tty(); |
799 | if (tty) { | 798 | if (tty) { |
800 | tty_pgrp = get_pid(tty->pgrp); | 799 | struct pid *tty_pgrp = get_pid(tty->pgrp); |
801 | if (on_exit) { | 800 | if (on_exit) { |
802 | if (tty->driver->type != TTY_DRIVER_TYPE_PTY) | 801 | if (tty->driver->type != TTY_DRIVER_TYPE_PTY) |
803 | tty_vhangup(tty); | 802 | tty_vhangup(tty); |
804 | } | 803 | } |
805 | tty_kref_put(tty); | 804 | tty_kref_put(tty); |
805 | if (tty_pgrp) { | ||
806 | kill_pgrp(tty_pgrp, SIGHUP, on_exit); | ||
807 | if (!on_exit) | ||
808 | kill_pgrp(tty_pgrp, SIGCONT, on_exit); | ||
809 | put_pid(tty_pgrp); | ||
810 | } | ||
806 | } else if (on_exit) { | 811 | } else if (on_exit) { |
807 | struct pid *old_pgrp; | 812 | struct pid *old_pgrp; |
808 | spin_lock_irq(¤t->sighand->siglock); | 813 | spin_lock_irq(¤t->sighand->siglock); |
@@ -816,12 +821,6 @@ void disassociate_ctty(int on_exit) | |||
816 | } | 821 | } |
817 | return; | 822 | return; |
818 | } | 823 | } |
819 | if (tty_pgrp) { | ||
820 | kill_pgrp(tty_pgrp, SIGHUP, on_exit); | ||
821 | if (!on_exit) | ||
822 | kill_pgrp(tty_pgrp, SIGCONT, on_exit); | ||
823 | put_pid(tty_pgrp); | ||
824 | } | ||
825 | 824 | ||
826 | spin_lock_irq(¤t->sighand->siglock); | 825 | spin_lock_irq(¤t->sighand->siglock); |
827 | put_pid(current->signal->tty_old_pgrp); | 826 | put_pid(current->signal->tty_old_pgrp); |
@@ -1558,6 +1557,59 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1558 | } | 1557 | } |
1559 | 1558 | ||
1560 | /** | 1559 | /** |
1560 | * tty_release_checks - check a tty before real release | ||
1561 | * @tty: tty to check | ||
1562 | * @o_tty: link of @tty (if any) | ||
1563 | * @idx: index of the tty | ||
1564 | * | ||
1565 | * Performs some paranoid checking before true release of the @tty. | ||
1566 | * This is a no-op unless TTY_PARANOIA_CHECK is defined. | ||
1567 | */ | ||
1568 | static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, | ||
1569 | int idx) | ||
1570 | { | ||
1571 | #ifdef TTY_PARANOIA_CHECK | ||
1572 | if (idx < 0 || idx >= tty->driver->num) { | ||
1573 | printk(KERN_DEBUG "%s: bad idx when trying to free (%s)\n", | ||
1574 | __func__, tty->name); | ||
1575 | return -1; | ||
1576 | } | ||
1577 | |||
1578 | /* not much to check for devpts */ | ||
1579 | if (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) | ||
1580 | return 0; | ||
1581 | |||
1582 | if (tty != tty->driver->ttys[idx]) { | ||
1583 | printk(KERN_DEBUG "%s: driver.table[%d] not tty for (%s)\n", | ||
1584 | __func__, idx, tty->name); | ||
1585 | return -1; | ||
1586 | } | ||
1587 | if (tty->termios != tty->driver->termios[idx]) { | ||
1588 | printk(KERN_DEBUG "%s: driver.termios[%d] not termios for (%s)\n", | ||
1589 | __func__, idx, tty->name); | ||
1590 | return -1; | ||
1591 | } | ||
1592 | if (tty->driver->other) { | ||
1593 | if (o_tty != tty->driver->other->ttys[idx]) { | ||
1594 | printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", | ||
1595 | __func__, idx, tty->name); | ||
1596 | return -1; | ||
1597 | } | ||
1598 | if (o_tty->termios != tty->driver->other->termios[idx]) { | ||
1599 | printk(KERN_DEBUG "%s: other->termios[%d] not o_termios for (%s)\n", | ||
1600 | __func__, idx, tty->name); | ||
1601 | return -1; | ||
1602 | } | ||
1603 | if (o_tty->link != tty) { | ||
1604 | printk(KERN_DEBUG "%s: bad pty pointers\n", __func__); | ||
1605 | return -1; | ||
1606 | } | ||
1607 | } | ||
1608 | #endif | ||
1609 | return 0; | ||
1610 | } | ||
1611 | |||
1612 | /** | ||
1561 | * tty_release - vfs callback for close | 1613 | * tty_release - vfs callback for close |
1562 | * @inode: inode of tty | 1614 | * @inode: inode of tty |
1563 | * @filp: file pointer for handle to tty | 1615 | * @filp: file pointer for handle to tty |
@@ -1585,11 +1637,11 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1585 | int idx; | 1637 | int idx; |
1586 | char buf[64]; | 1638 | char buf[64]; |
1587 | 1639 | ||
1588 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) | 1640 | if (tty_paranoia_check(tty, inode, __func__)) |
1589 | return 0; | 1641 | return 0; |
1590 | 1642 | ||
1591 | tty_lock(); | 1643 | tty_lock(); |
1592 | check_tty_count(tty, "tty_release_dev"); | 1644 | check_tty_count(tty, __func__); |
1593 | 1645 | ||
1594 | __tty_fasync(-1, filp, 0); | 1646 | __tty_fasync(-1, filp, 0); |
1595 | 1647 | ||
@@ -1599,59 +1651,16 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1599 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | 1651 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
1600 | o_tty = tty->link; | 1652 | o_tty = tty->link; |
1601 | 1653 | ||
1602 | #ifdef TTY_PARANOIA_CHECK | 1654 | if (tty_release_checks(tty, o_tty, idx)) { |
1603 | if (idx < 0 || idx >= tty->driver->num) { | ||
1604 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " | ||
1605 | "free (%s)\n", tty->name); | ||
1606 | tty_unlock(); | 1655 | tty_unlock(); |
1607 | return 0; | 1656 | return 0; |
1608 | } | 1657 | } |
1609 | if (!devpts) { | ||
1610 | if (tty != tty->driver->ttys[idx]) { | ||
1611 | tty_unlock(); | ||
1612 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " | ||
1613 | "for (%s)\n", idx, tty->name); | ||
1614 | return 0; | ||
1615 | } | ||
1616 | if (tty->termios != tty->driver->termios[idx]) { | ||
1617 | tty_unlock(); | ||
1618 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " | ||
1619 | "for (%s)\n", | ||
1620 | idx, tty->name); | ||
1621 | return 0; | ||
1622 | } | ||
1623 | } | ||
1624 | #endif | ||
1625 | 1658 | ||
1626 | #ifdef TTY_DEBUG_HANGUP | 1659 | #ifdef TTY_DEBUG_HANGUP |
1627 | printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...", | 1660 | printk(KERN_DEBUG "%s: %s (tty count=%d)...\n", __func__, |
1628 | tty_name(tty, buf), tty->count); | 1661 | tty_name(tty, buf), tty->count); |
1629 | #endif | 1662 | #endif |
1630 | 1663 | ||
1631 | #ifdef TTY_PARANOIA_CHECK | ||
1632 | if (tty->driver->other && | ||
1633 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | ||
1634 | if (o_tty != tty->driver->other->ttys[idx]) { | ||
1635 | tty_unlock(); | ||
1636 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " | ||
1637 | "not o_tty for (%s)\n", | ||
1638 | idx, tty->name); | ||
1639 | return 0 ; | ||
1640 | } | ||
1641 | if (o_tty->termios != tty->driver->other->termios[idx]) { | ||
1642 | tty_unlock(); | ||
1643 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " | ||
1644 | "not o_termios for (%s)\n", | ||
1645 | idx, tty->name); | ||
1646 | return 0; | ||
1647 | } | ||
1648 | if (o_tty->link != tty) { | ||
1649 | tty_unlock(); | ||
1650 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); | ||
1651 | return 0; | ||
1652 | } | ||
1653 | } | ||
1654 | #endif | ||
1655 | if (tty->ops->close) | 1664 | if (tty->ops->close) |
1656 | tty->ops->close(tty, filp); | 1665 | tty->ops->close(tty, filp); |
1657 | 1666 | ||
@@ -1707,8 +1716,8 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1707 | if (!do_sleep) | 1716 | if (!do_sleep) |
1708 | break; | 1717 | break; |
1709 | 1718 | ||
1710 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " | 1719 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
1711 | "active!\n", tty_name(tty, buf)); | 1720 | __func__, tty_name(tty, buf)); |
1712 | tty_unlock(); | 1721 | tty_unlock(); |
1713 | mutex_unlock(&tty_mutex); | 1722 | mutex_unlock(&tty_mutex); |
1714 | schedule(); | 1723 | schedule(); |
@@ -1721,15 +1730,14 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1721 | */ | 1730 | */ |
1722 | if (pty_master) { | 1731 | if (pty_master) { |
1723 | if (--o_tty->count < 0) { | 1732 | if (--o_tty->count < 0) { |
1724 | printk(KERN_WARNING "tty_release_dev: bad pty slave count " | 1733 | printk(KERN_WARNING "%s: bad pty slave count (%d) for %s\n", |
1725 | "(%d) for %s\n", | 1734 | __func__, o_tty->count, tty_name(o_tty, buf)); |
1726 | o_tty->count, tty_name(o_tty, buf)); | ||
1727 | o_tty->count = 0; | 1735 | o_tty->count = 0; |
1728 | } | 1736 | } |
1729 | } | 1737 | } |
1730 | if (--tty->count < 0) { | 1738 | if (--tty->count < 0) { |
1731 | printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n", | 1739 | printk(KERN_WARNING "%s: bad tty->count (%d) for %s\n", |
1732 | tty->count, tty_name(tty, buf)); | 1740 | __func__, tty->count, tty_name(tty, buf)); |
1733 | tty->count = 0; | 1741 | tty->count = 0; |
1734 | } | 1742 | } |
1735 | 1743 | ||
@@ -1778,7 +1786,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1778 | } | 1786 | } |
1779 | 1787 | ||
1780 | #ifdef TTY_DEBUG_HANGUP | 1788 | #ifdef TTY_DEBUG_HANGUP |
1781 | printk(KERN_DEBUG "freeing tty structure..."); | 1789 | printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); |
1782 | #endif | 1790 | #endif |
1783 | /* | 1791 | /* |
1784 | * Ask the line discipline code to release its structures | 1792 | * Ask the line discipline code to release its structures |
@@ -1798,6 +1806,83 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1798 | } | 1806 | } |
1799 | 1807 | ||
1800 | /** | 1808 | /** |
1809 | * tty_open_current_tty - get tty of current task for open | ||
1810 | * @device: device number | ||
1811 | * @filp: file pointer to tty | ||
1812 | * @return: tty of the current task iff @device is /dev/tty | ||
1813 | * | ||
1814 | * We cannot return driver and index like for the other nodes because | ||
1815 | * devpts will not work then. It expects inodes to be from devpts FS. | ||
1816 | */ | ||
1817 | static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) | ||
1818 | { | ||
1819 | struct tty_struct *tty; | ||
1820 | |||
1821 | if (device != MKDEV(TTYAUX_MAJOR, 0)) | ||
1822 | return NULL; | ||
1823 | |||
1824 | tty = get_current_tty(); | ||
1825 | if (!tty) | ||
1826 | return ERR_PTR(-ENXIO); | ||
1827 | |||
1828 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ | ||
1829 | /* noctty = 1; */ | ||
1830 | tty_kref_put(tty); | ||
1831 | /* FIXME: we put a reference and return a TTY! */ | ||
1832 | return tty; | ||
1833 | } | ||
1834 | |||
1835 | /** | ||
1836 | * tty_lookup_driver - lookup a tty driver for a given device file | ||
1837 | * @device: device number | ||
1838 | * @filp: file pointer to tty | ||
1839 | * @noctty: set if the device should not become a controlling tty | ||
1840 | * @index: index for the device in the @return driver | ||
1841 | * @return: driver for this inode (with increased refcount) | ||
1842 | * | ||
1843 | * If @return is not erroneous, the caller is responsible to decrement the | ||
1844 | * refcount by tty_driver_kref_put. | ||
1845 | * | ||
1846 | * Locking: tty_mutex protects get_tty_driver | ||
1847 | */ | ||
1848 | static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | ||
1849 | int *noctty, int *index) | ||
1850 | { | ||
1851 | struct tty_driver *driver; | ||
1852 | |||
1853 | switch (device) { | ||
1854 | #ifdef CONFIG_VT | ||
1855 | case MKDEV(TTY_MAJOR, 0): { | ||
1856 | extern struct tty_driver *console_driver; | ||
1857 | driver = tty_driver_kref_get(console_driver); | ||
1858 | *index = fg_console; | ||
1859 | *noctty = 1; | ||
1860 | break; | ||
1861 | } | ||
1862 | #endif | ||
1863 | case MKDEV(TTYAUX_MAJOR, 1): { | ||
1864 | struct tty_driver *console_driver = console_device(index); | ||
1865 | if (console_driver) { | ||
1866 | driver = tty_driver_kref_get(console_driver); | ||
1867 | if (driver) { | ||
1868 | /* Don't let /dev/console block */ | ||
1869 | filp->f_flags |= O_NONBLOCK; | ||
1870 | *noctty = 1; | ||
1871 | break; | ||
1872 | } | ||
1873 | } | ||
1874 | return ERR_PTR(-ENODEV); | ||
1875 | } | ||
1876 | default: | ||
1877 | driver = get_tty_driver(device, index); | ||
1878 | if (!driver) | ||
1879 | return ERR_PTR(-ENODEV); | ||
1880 | break; | ||
1881 | } | ||
1882 | return driver; | ||
1883 | } | ||
1884 | |||
1885 | /** | ||
1801 | * tty_open - open a tty device | 1886 | * tty_open - open a tty device |
1802 | * @inode: inode of device file | 1887 | * @inode: inode of device file |
1803 | * @filp: file pointer to tty | 1888 | * @filp: file pointer to tty |
@@ -1813,16 +1898,16 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1813 | * The termios state of a pty is reset on first open so that | 1898 | * The termios state of a pty is reset on first open so that |
1814 | * settings don't persist across reuse. | 1899 | * settings don't persist across reuse. |
1815 | * | 1900 | * |
1816 | * Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work. | 1901 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
1817 | * tty->count should protect the rest. | 1902 | * tty->count should protect the rest. |
1818 | * ->siglock protects ->signal/->sighand | 1903 | * ->siglock protects ->signal/->sighand |
1819 | */ | 1904 | */ |
1820 | 1905 | ||
1821 | static int tty_open(struct inode *inode, struct file *filp) | 1906 | static int tty_open(struct inode *inode, struct file *filp) |
1822 | { | 1907 | { |
1823 | struct tty_struct *tty = NULL; | 1908 | struct tty_struct *tty; |
1824 | int noctty, retval; | 1909 | int noctty, retval; |
1825 | struct tty_driver *driver; | 1910 | struct tty_driver *driver = NULL; |
1826 | int index; | 1911 | int index; |
1827 | dev_t device = inode->i_rdev; | 1912 | dev_t device = inode->i_rdev; |
1828 | unsigned saved_flags = filp->f_flags; | 1913 | unsigned saved_flags = filp->f_flags; |
@@ -1841,66 +1926,22 @@ retry_open: | |||
1841 | mutex_lock(&tty_mutex); | 1926 | mutex_lock(&tty_mutex); |
1842 | tty_lock(); | 1927 | tty_lock(); |
1843 | 1928 | ||
1844 | if (device == MKDEV(TTYAUX_MAJOR, 0)) { | 1929 | tty = tty_open_current_tty(device, filp); |
1845 | tty = get_current_tty(); | 1930 | if (IS_ERR(tty)) { |
1846 | if (!tty) { | 1931 | retval = PTR_ERR(tty); |
1847 | tty_unlock(); | 1932 | goto err_unlock; |
1848 | mutex_unlock(&tty_mutex); | 1933 | } else if (!tty) { |
1849 | tty_free_file(filp); | 1934 | driver = tty_lookup_driver(device, filp, &noctty, &index); |
1850 | return -ENXIO; | 1935 | if (IS_ERR(driver)) { |
1851 | } | 1936 | retval = PTR_ERR(driver); |
1852 | driver = tty_driver_kref_get(tty->driver); | 1937 | goto err_unlock; |
1853 | index = tty->index; | ||
1854 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ | ||
1855 | /* noctty = 1; */ | ||
1856 | /* FIXME: Should we take a driver reference ? */ | ||
1857 | tty_kref_put(tty); | ||
1858 | goto got_driver; | ||
1859 | } | ||
1860 | #ifdef CONFIG_VT | ||
1861 | if (device == MKDEV(TTY_MAJOR, 0)) { | ||
1862 | extern struct tty_driver *console_driver; | ||
1863 | driver = tty_driver_kref_get(console_driver); | ||
1864 | index = fg_console; | ||
1865 | noctty = 1; | ||
1866 | goto got_driver; | ||
1867 | } | ||
1868 | #endif | ||
1869 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { | ||
1870 | struct tty_driver *console_driver = console_device(&index); | ||
1871 | if (console_driver) { | ||
1872 | driver = tty_driver_kref_get(console_driver); | ||
1873 | if (driver) { | ||
1874 | /* Don't let /dev/console block */ | ||
1875 | filp->f_flags |= O_NONBLOCK; | ||
1876 | noctty = 1; | ||
1877 | goto got_driver; | ||
1878 | } | ||
1879 | } | 1938 | } |
1880 | tty_unlock(); | ||
1881 | mutex_unlock(&tty_mutex); | ||
1882 | tty_free_file(filp); | ||
1883 | return -ENODEV; | ||
1884 | } | ||
1885 | 1939 | ||
1886 | driver = get_tty_driver(device, &index); | ||
1887 | if (!driver) { | ||
1888 | tty_unlock(); | ||
1889 | mutex_unlock(&tty_mutex); | ||
1890 | tty_free_file(filp); | ||
1891 | return -ENODEV; | ||
1892 | } | ||
1893 | got_driver: | ||
1894 | if (!tty) { | ||
1895 | /* check whether we're reopening an existing tty */ | 1940 | /* check whether we're reopening an existing tty */ |
1896 | tty = tty_driver_lookup_tty(driver, inode, index); | 1941 | tty = tty_driver_lookup_tty(driver, inode, index); |
1897 | |||
1898 | if (IS_ERR(tty)) { | 1942 | if (IS_ERR(tty)) { |
1899 | tty_unlock(); | 1943 | retval = PTR_ERR(tty); |
1900 | mutex_unlock(&tty_mutex); | 1944 | goto err_unlock; |
1901 | tty_driver_kref_put(driver); | ||
1902 | tty_free_file(filp); | ||
1903 | return PTR_ERR(tty); | ||
1904 | } | 1945 | } |
1905 | } | 1946 | } |
1906 | 1947 | ||
@@ -1912,21 +1953,22 @@ got_driver: | |||
1912 | tty = tty_init_dev(driver, index, 0); | 1953 | tty = tty_init_dev(driver, index, 0); |
1913 | 1954 | ||
1914 | mutex_unlock(&tty_mutex); | 1955 | mutex_unlock(&tty_mutex); |
1915 | tty_driver_kref_put(driver); | 1956 | if (driver) |
1957 | tty_driver_kref_put(driver); | ||
1916 | if (IS_ERR(tty)) { | 1958 | if (IS_ERR(tty)) { |
1917 | tty_unlock(); | 1959 | tty_unlock(); |
1918 | tty_free_file(filp); | 1960 | retval = PTR_ERR(tty); |
1919 | return PTR_ERR(tty); | 1961 | goto err_file; |
1920 | } | 1962 | } |
1921 | 1963 | ||
1922 | tty_add_file(tty, filp); | 1964 | tty_add_file(tty, filp); |
1923 | 1965 | ||
1924 | check_tty_count(tty, "tty_open"); | 1966 | check_tty_count(tty, __func__); |
1925 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1967 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1926 | tty->driver->subtype == PTY_TYPE_MASTER) | 1968 | tty->driver->subtype == PTY_TYPE_MASTER) |
1927 | noctty = 1; | 1969 | noctty = 1; |
1928 | #ifdef TTY_DEBUG_HANGUP | 1970 | #ifdef TTY_DEBUG_HANGUP |
1929 | printk(KERN_DEBUG "opening %s...", tty->name); | 1971 | printk(KERN_DEBUG "%s: opening %s...\n", __func__, tty->name); |
1930 | #endif | 1972 | #endif |
1931 | if (tty->ops->open) | 1973 | if (tty->ops->open) |
1932 | retval = tty->ops->open(tty, filp); | 1974 | retval = tty->ops->open(tty, filp); |
@@ -1940,8 +1982,8 @@ got_driver: | |||
1940 | 1982 | ||
1941 | if (retval) { | 1983 | if (retval) { |
1942 | #ifdef TTY_DEBUG_HANGUP | 1984 | #ifdef TTY_DEBUG_HANGUP |
1943 | printk(KERN_DEBUG "error %d in opening %s...", retval, | 1985 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, |
1944 | tty->name); | 1986 | retval, tty->name); |
1945 | #endif | 1987 | #endif |
1946 | tty_unlock(); /* need to call tty_release without BTM */ | 1988 | tty_unlock(); /* need to call tty_release without BTM */ |
1947 | tty_release(inode, filp); | 1989 | tty_release(inode, filp); |
@@ -1976,6 +2018,15 @@ got_driver: | |||
1976 | tty_unlock(); | 2018 | tty_unlock(); |
1977 | mutex_unlock(&tty_mutex); | 2019 | mutex_unlock(&tty_mutex); |
1978 | return 0; | 2020 | return 0; |
2021 | err_unlock: | ||
2022 | tty_unlock(); | ||
2023 | mutex_unlock(&tty_mutex); | ||
2024 | /* after locks to avoid deadlock */ | ||
2025 | if (!IS_ERR_OR_NULL(driver)) | ||
2026 | tty_driver_kref_put(driver); | ||
2027 | err_file: | ||
2028 | tty_free_file(filp); | ||
2029 | return retval; | ||
1979 | } | 2030 | } |
1980 | 2031 | ||
1981 | 2032 | ||