diff options
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 375 |
1 files changed, 250 insertions, 125 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b425c79675ad..8a5a8b064616 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -181,10 +181,13 @@ struct tty_struct *alloc_tty_struct(void) | |||
181 | 181 | ||
182 | void free_tty_struct(struct tty_struct *tty) | 182 | void free_tty_struct(struct tty_struct *tty) |
183 | { | 183 | { |
184 | if (!tty) | ||
185 | return; | ||
184 | if (tty->dev) | 186 | if (tty->dev) |
185 | put_device(tty->dev); | 187 | put_device(tty->dev); |
186 | kfree(tty->write_buf); | 188 | kfree(tty->write_buf); |
187 | tty_buffer_free_all(tty); | 189 | tty_buffer_free_all(tty); |
190 | tty->magic = 0xDEADDEAD; | ||
188 | kfree(tty); | 191 | kfree(tty); |
189 | } | 192 | } |
190 | 193 | ||
@@ -573,7 +576,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
573 | } | 576 | } |
574 | spin_unlock(&redirect_lock); | 577 | spin_unlock(&redirect_lock); |
575 | 578 | ||
576 | tty_lock(); | 579 | tty_lock(tty); |
577 | 580 | ||
578 | /* some functions below drop BTM, so we need this bit */ | 581 | /* some functions below drop BTM, so we need this bit */ |
579 | set_bit(TTY_HUPPING, &tty->flags); | 582 | set_bit(TTY_HUPPING, &tty->flags); |
@@ -666,7 +669,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
666 | clear_bit(TTY_HUPPING, &tty->flags); | 669 | clear_bit(TTY_HUPPING, &tty->flags); |
667 | tty_ldisc_enable(tty); | 670 | tty_ldisc_enable(tty); |
668 | 671 | ||
669 | tty_unlock(); | 672 | tty_unlock(tty); |
670 | 673 | ||
671 | if (f) | 674 | if (f) |
672 | fput(f); | 675 | fput(f); |
@@ -1103,12 +1106,12 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
1103 | { | 1106 | { |
1104 | if (tty) { | 1107 | if (tty) { |
1105 | mutex_lock(&tty->atomic_write_lock); | 1108 | mutex_lock(&tty->atomic_write_lock); |
1106 | tty_lock(); | 1109 | tty_lock(tty); |
1107 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { | 1110 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { |
1108 | tty_unlock(); | 1111 | tty_unlock(tty); |
1109 | tty->ops->write(tty, msg, strlen(msg)); | 1112 | tty->ops->write(tty, msg, strlen(msg)); |
1110 | } else | 1113 | } else |
1111 | tty_unlock(); | 1114 | tty_unlock(tty); |
1112 | tty_write_unlock(tty); | 1115 | tty_write_unlock(tty); |
1113 | } | 1116 | } |
1114 | return; | 1117 | return; |
@@ -1213,7 +1216,10 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) | |||
1213 | */ | 1216 | */ |
1214 | static void tty_line_name(struct tty_driver *driver, int index, char *p) | 1217 | static void tty_line_name(struct tty_driver *driver, int index, char *p) |
1215 | { | 1218 | { |
1216 | sprintf(p, "%s%d", driver->name, index + driver->name_base); | 1219 | if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE) |
1220 | strcpy(p, driver->name); | ||
1221 | else | ||
1222 | sprintf(p, "%s%d", driver->name, index + driver->name_base); | ||
1217 | } | 1223 | } |
1218 | 1224 | ||
1219 | /** | 1225 | /** |
@@ -1249,21 +1255,19 @@ int tty_init_termios(struct tty_struct *tty) | |||
1249 | struct ktermios *tp; | 1255 | struct ktermios *tp; |
1250 | int idx = tty->index; | 1256 | int idx = tty->index; |
1251 | 1257 | ||
1252 | tp = tty->driver->termios[idx]; | 1258 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
1253 | if (tp == NULL) { | 1259 | tty->termios = tty->driver->init_termios; |
1254 | tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | 1260 | else { |
1255 | if (tp == NULL) | 1261 | /* Check for lazy saved data */ |
1256 | return -ENOMEM; | 1262 | tp = tty->driver->termios[idx]; |
1257 | memcpy(tp, &tty->driver->init_termios, | 1263 | if (tp != NULL) |
1258 | sizeof(struct ktermios)); | 1264 | tty->termios = *tp; |
1259 | tty->driver->termios[idx] = tp; | 1265 | else |
1266 | tty->termios = tty->driver->init_termios; | ||
1260 | } | 1267 | } |
1261 | tty->termios = tp; | ||
1262 | tty->termios_locked = tp + 1; | ||
1263 | |||
1264 | /* Compatibility until drivers always set this */ | 1268 | /* Compatibility until drivers always set this */ |
1265 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | 1269 | tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); |
1266 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | 1270 | tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); |
1267 | return 0; | 1271 | return 0; |
1268 | } | 1272 | } |
1269 | EXPORT_SYMBOL_GPL(tty_init_termios); | 1273 | EXPORT_SYMBOL_GPL(tty_init_termios); |
@@ -1403,10 +1407,18 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1403 | } | 1407 | } |
1404 | initialize_tty_struct(tty, driver, idx); | 1408 | initialize_tty_struct(tty, driver, idx); |
1405 | 1409 | ||
1410 | tty_lock(tty); | ||
1406 | retval = tty_driver_install_tty(driver, tty); | 1411 | retval = tty_driver_install_tty(driver, tty); |
1407 | if (retval < 0) | 1412 | if (retval < 0) |
1408 | goto err_deinit_tty; | 1413 | goto err_deinit_tty; |
1409 | 1414 | ||
1415 | if (!tty->port) | ||
1416 | tty->port = driver->ports[idx]; | ||
1417 | |||
1418 | WARN_RATELIMIT(!tty->port, | ||
1419 | "%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", | ||
1420 | __func__, tty->driver->name); | ||
1421 | |||
1410 | /* | 1422 | /* |
1411 | * Structures all installed ... call the ldisc open routines. | 1423 | * Structures all installed ... call the ldisc open routines. |
1412 | * If we fail here just call release_tty to clean up. No need | 1424 | * If we fail here just call release_tty to clean up. No need |
@@ -1415,9 +1427,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1415 | retval = tty_ldisc_setup(tty, tty->link); | 1427 | retval = tty_ldisc_setup(tty, tty->link); |
1416 | if (retval) | 1428 | if (retval) |
1417 | goto err_release_tty; | 1429 | goto err_release_tty; |
1430 | /* Return the tty locked so that it cannot vanish under the caller */ | ||
1418 | return tty; | 1431 | return tty; |
1419 | 1432 | ||
1420 | err_deinit_tty: | 1433 | err_deinit_tty: |
1434 | tty_unlock(tty); | ||
1421 | deinitialize_tty_struct(tty); | 1435 | deinitialize_tty_struct(tty); |
1422 | free_tty_struct(tty); | 1436 | free_tty_struct(tty); |
1423 | err_module_put: | 1437 | err_module_put: |
@@ -1426,6 +1440,7 @@ err_module_put: | |||
1426 | 1440 | ||
1427 | /* call the tty release_tty routine to clean out this slot */ | 1441 | /* call the tty release_tty routine to clean out this slot */ |
1428 | err_release_tty: | 1442 | err_release_tty: |
1443 | tty_unlock(tty); | ||
1429 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " | 1444 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " |
1430 | "clearing slot %d\n", idx); | 1445 | "clearing slot %d\n", idx); |
1431 | release_tty(tty, idx); | 1446 | release_tty(tty, idx); |
@@ -1436,22 +1451,25 @@ void tty_free_termios(struct tty_struct *tty) | |||
1436 | { | 1451 | { |
1437 | struct ktermios *tp; | 1452 | struct ktermios *tp; |
1438 | int idx = tty->index; | 1453 | int idx = tty->index; |
1439 | /* Kill this flag and push into drivers for locking etc */ | 1454 | |
1440 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | 1455 | /* If the port is going to reset then it has no termios to save */ |
1441 | /* FIXME: Locking on ->termios array */ | 1456 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
1442 | tp = tty->termios; | 1457 | return; |
1443 | tty->driver->termios[idx] = NULL; | 1458 | |
1444 | kfree(tp); | 1459 | /* Stash the termios data */ |
1460 | tp = tty->driver->termios[idx]; | ||
1461 | if (tp == NULL) { | ||
1462 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1463 | if (tp == NULL) { | ||
1464 | pr_warn("tty: no memory to save termios state.\n"); | ||
1465 | return; | ||
1466 | } | ||
1467 | tty->driver->termios[idx] = tp; | ||
1445 | } | 1468 | } |
1469 | *tp = tty->termios; | ||
1446 | } | 1470 | } |
1447 | EXPORT_SYMBOL(tty_free_termios); | 1471 | EXPORT_SYMBOL(tty_free_termios); |
1448 | 1472 | ||
1449 | void tty_shutdown(struct tty_struct *tty) | ||
1450 | { | ||
1451 | tty_driver_remove_tty(tty->driver, tty); | ||
1452 | tty_free_termios(tty); | ||
1453 | } | ||
1454 | EXPORT_SYMBOL(tty_shutdown); | ||
1455 | 1473 | ||
1456 | /** | 1474 | /** |
1457 | * release_one_tty - release tty structure memory | 1475 | * release_one_tty - release tty structure memory |
@@ -1462,7 +1480,6 @@ EXPORT_SYMBOL(tty_shutdown); | |||
1462 | * in use. It also gets called when setup of a device fails. | 1480 | * in use. It also gets called when setup of a device fails. |
1463 | * | 1481 | * |
1464 | * Locking: | 1482 | * Locking: |
1465 | * tty_mutex - sometimes only | ||
1466 | * takes the file list lock internally when working on the list | 1483 | * takes the file list lock internally when working on the list |
1467 | * of ttys that the driver keeps. | 1484 | * of ttys that the driver keeps. |
1468 | * | 1485 | * |
@@ -1495,11 +1512,6 @@ static void queue_release_one_tty(struct kref *kref) | |||
1495 | { | 1512 | { |
1496 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); | 1513 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
1497 | 1514 | ||
1498 | if (tty->ops->shutdown) | ||
1499 | tty->ops->shutdown(tty); | ||
1500 | else | ||
1501 | tty_shutdown(tty); | ||
1502 | |||
1503 | /* The hangup queue is now free so we can reuse it rather than | 1515 | /* The hangup queue is now free so we can reuse it rather than |
1504 | waste a chunk of memory for each port */ | 1516 | waste a chunk of memory for each port */ |
1505 | INIT_WORK(&tty->hangup_work, release_one_tty); | 1517 | INIT_WORK(&tty->hangup_work, release_one_tty); |
@@ -1528,16 +1540,20 @@ EXPORT_SYMBOL(tty_kref_put); | |||
1528 | * and decrement the refcount of the backing module. | 1540 | * and decrement the refcount of the backing module. |
1529 | * | 1541 | * |
1530 | * Locking: | 1542 | * Locking: |
1531 | * tty_mutex - sometimes only | 1543 | * tty_mutex |
1532 | * takes the file list lock internally when working on the list | 1544 | * takes the file list lock internally when working on the list |
1533 | * of ttys that the driver keeps. | 1545 | * of ttys that the driver keeps. |
1534 | * FIXME: should we require tty_mutex is held here ?? | ||
1535 | * | 1546 | * |
1536 | */ | 1547 | */ |
1537 | static void release_tty(struct tty_struct *tty, int idx) | 1548 | static void release_tty(struct tty_struct *tty, int idx) |
1538 | { | 1549 | { |
1539 | /* This should always be true but check for the moment */ | 1550 | /* This should always be true but check for the moment */ |
1540 | WARN_ON(tty->index != idx); | 1551 | WARN_ON(tty->index != idx); |
1552 | WARN_ON(!mutex_is_locked(&tty_mutex)); | ||
1553 | if (tty->ops->shutdown) | ||
1554 | tty->ops->shutdown(tty); | ||
1555 | tty_free_termios(tty); | ||
1556 | tty_driver_remove_tty(tty->driver, tty); | ||
1541 | 1557 | ||
1542 | if (tty->link) | 1558 | if (tty->link) |
1543 | tty_kref_put(tty->link); | 1559 | tty_kref_put(tty->link); |
@@ -1572,22 +1588,12 @@ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, | |||
1572 | __func__, idx, tty->name); | 1588 | __func__, idx, tty->name); |
1573 | return -1; | 1589 | return -1; |
1574 | } | 1590 | } |
1575 | if (tty->termios != tty->driver->termios[idx]) { | ||
1576 | printk(KERN_DEBUG "%s: driver.termios[%d] not termios for (%s)\n", | ||
1577 | __func__, idx, tty->name); | ||
1578 | return -1; | ||
1579 | } | ||
1580 | if (tty->driver->other) { | 1591 | if (tty->driver->other) { |
1581 | if (o_tty != tty->driver->other->ttys[idx]) { | 1592 | if (o_tty != tty->driver->other->ttys[idx]) { |
1582 | printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", | 1593 | printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", |
1583 | __func__, idx, tty->name); | 1594 | __func__, idx, tty->name); |
1584 | return -1; | 1595 | return -1; |
1585 | } | 1596 | } |
1586 | if (o_tty->termios != tty->driver->other->termios[idx]) { | ||
1587 | printk(KERN_DEBUG "%s: other->termios[%d] not o_termios for (%s)\n", | ||
1588 | __func__, idx, tty->name); | ||
1589 | return -1; | ||
1590 | } | ||
1591 | if (o_tty->link != tty) { | 1597 | if (o_tty->link != tty) { |
1592 | printk(KERN_DEBUG "%s: bad pty pointers\n", __func__); | 1598 | printk(KERN_DEBUG "%s: bad pty pointers\n", __func__); |
1593 | return -1; | 1599 | return -1; |
@@ -1628,7 +1634,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1628 | if (tty_paranoia_check(tty, inode, __func__)) | 1634 | if (tty_paranoia_check(tty, inode, __func__)) |
1629 | return 0; | 1635 | return 0; |
1630 | 1636 | ||
1631 | tty_lock(); | 1637 | tty_lock(tty); |
1632 | check_tty_count(tty, __func__); | 1638 | check_tty_count(tty, __func__); |
1633 | 1639 | ||
1634 | __tty_fasync(-1, filp, 0); | 1640 | __tty_fasync(-1, filp, 0); |
@@ -1637,10 +1643,11 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1637 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1643 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1638 | tty->driver->subtype == PTY_TYPE_MASTER); | 1644 | tty->driver->subtype == PTY_TYPE_MASTER); |
1639 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | 1645 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
1646 | /* Review: parallel close */ | ||
1640 | o_tty = tty->link; | 1647 | o_tty = tty->link; |
1641 | 1648 | ||
1642 | if (tty_release_checks(tty, o_tty, idx)) { | 1649 | if (tty_release_checks(tty, o_tty, idx)) { |
1643 | tty_unlock(); | 1650 | tty_unlock(tty); |
1644 | return 0; | 1651 | return 0; |
1645 | } | 1652 | } |
1646 | 1653 | ||
@@ -1652,7 +1659,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1652 | if (tty->ops->close) | 1659 | if (tty->ops->close) |
1653 | tty->ops->close(tty, filp); | 1660 | tty->ops->close(tty, filp); |
1654 | 1661 | ||
1655 | tty_unlock(); | 1662 | tty_unlock(tty); |
1656 | /* | 1663 | /* |
1657 | * Sanity check: if tty->count is going to zero, there shouldn't be | 1664 | * Sanity check: if tty->count is going to zero, there shouldn't be |
1658 | * any waiters on tty->read_wait or tty->write_wait. We test the | 1665 | * any waiters on tty->read_wait or tty->write_wait. We test the |
@@ -1675,7 +1682,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1675 | opens on /dev/tty */ | 1682 | opens on /dev/tty */ |
1676 | 1683 | ||
1677 | mutex_lock(&tty_mutex); | 1684 | mutex_lock(&tty_mutex); |
1678 | tty_lock(); | 1685 | tty_lock_pair(tty, o_tty); |
1679 | tty_closing = tty->count <= 1; | 1686 | tty_closing = tty->count <= 1; |
1680 | o_tty_closing = o_tty && | 1687 | o_tty_closing = o_tty && |
1681 | (o_tty->count <= (pty_master ? 1 : 0)); | 1688 | (o_tty->count <= (pty_master ? 1 : 0)); |
@@ -1706,7 +1713,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1706 | 1713 | ||
1707 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", | 1714 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
1708 | __func__, tty_name(tty, buf)); | 1715 | __func__, tty_name(tty, buf)); |
1709 | tty_unlock(); | 1716 | tty_unlock_pair(tty, o_tty); |
1710 | mutex_unlock(&tty_mutex); | 1717 | mutex_unlock(&tty_mutex); |
1711 | schedule(); | 1718 | schedule(); |
1712 | } | 1719 | } |
@@ -1715,6 +1722,9 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1715 | * The closing flags are now consistent with the open counts on | 1722 | * The closing flags are now consistent with the open counts on |
1716 | * both sides, and we've completed the last operation that could | 1723 | * both sides, and we've completed the last operation that could |
1717 | * block, so it's safe to proceed with closing. | 1724 | * block, so it's safe to proceed with closing. |
1725 | * | ||
1726 | * We must *not* drop the tty_mutex until we ensure that a further | ||
1727 | * entry into tty_open can not pick up this tty. | ||
1718 | */ | 1728 | */ |
1719 | if (pty_master) { | 1729 | if (pty_master) { |
1720 | if (--o_tty->count < 0) { | 1730 | if (--o_tty->count < 0) { |
@@ -1766,12 +1776,13 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1766 | } | 1776 | } |
1767 | 1777 | ||
1768 | mutex_unlock(&tty_mutex); | 1778 | mutex_unlock(&tty_mutex); |
1779 | tty_unlock_pair(tty, o_tty); | ||
1780 | /* At this point the TTY_CLOSING flag should ensure a dead tty | ||
1781 | cannot be re-opened by a racing opener */ | ||
1769 | 1782 | ||
1770 | /* check whether both sides are closing ... */ | 1783 | /* check whether both sides are closing ... */ |
1771 | if (!tty_closing || (o_tty && !o_tty_closing)) { | 1784 | if (!tty_closing || (o_tty && !o_tty_closing)) |
1772 | tty_unlock(); | ||
1773 | return 0; | 1785 | return 0; |
1774 | } | ||
1775 | 1786 | ||
1776 | #ifdef TTY_DEBUG_HANGUP | 1787 | #ifdef TTY_DEBUG_HANGUP |
1777 | printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); | 1788 | printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); |
@@ -1782,14 +1793,17 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1782 | tty_ldisc_release(tty, o_tty); | 1793 | tty_ldisc_release(tty, o_tty); |
1783 | /* | 1794 | /* |
1784 | * The release_tty function takes care of the details of clearing | 1795 | * The release_tty function takes care of the details of clearing |
1785 | * the slots and preserving the termios structure. | 1796 | * the slots and preserving the termios structure. The tty_unlock_pair |
1797 | * should be safe as we keep a kref while the tty is locked (so the | ||
1798 | * unlock never unlocks a freed tty). | ||
1786 | */ | 1799 | */ |
1800 | mutex_lock(&tty_mutex); | ||
1787 | release_tty(tty, idx); | 1801 | release_tty(tty, idx); |
1802 | mutex_unlock(&tty_mutex); | ||
1788 | 1803 | ||
1789 | /* Make this pty number available for reallocation */ | 1804 | /* Make this pty number available for reallocation */ |
1790 | if (devpts) | 1805 | if (devpts) |
1791 | devpts_kill_index(inode, idx); | 1806 | devpts_kill_index(inode, idx); |
1792 | tty_unlock(); | ||
1793 | return 0; | 1807 | return 0; |
1794 | } | 1808 | } |
1795 | 1809 | ||
@@ -1893,6 +1907,9 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | |||
1893 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. | 1907 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
1894 | * tty->count should protect the rest. | 1908 | * tty->count should protect the rest. |
1895 | * ->siglock protects ->signal/->sighand | 1909 | * ->siglock protects ->signal/->sighand |
1910 | * | ||
1911 | * Note: the tty_unlock/lock cases without a ref are only safe due to | ||
1912 | * tty_mutex | ||
1896 | */ | 1913 | */ |
1897 | 1914 | ||
1898 | static int tty_open(struct inode *inode, struct file *filp) | 1915 | static int tty_open(struct inode *inode, struct file *filp) |
@@ -1916,8 +1933,7 @@ retry_open: | |||
1916 | retval = 0; | 1933 | retval = 0; |
1917 | 1934 | ||
1918 | mutex_lock(&tty_mutex); | 1935 | mutex_lock(&tty_mutex); |
1919 | tty_lock(); | 1936 | /* This is protected by the tty_mutex */ |
1920 | |||
1921 | tty = tty_open_current_tty(device, filp); | 1937 | tty = tty_open_current_tty(device, filp); |
1922 | if (IS_ERR(tty)) { | 1938 | if (IS_ERR(tty)) { |
1923 | retval = PTR_ERR(tty); | 1939 | retval = PTR_ERR(tty); |
@@ -1938,17 +1954,19 @@ retry_open: | |||
1938 | } | 1954 | } |
1939 | 1955 | ||
1940 | if (tty) { | 1956 | if (tty) { |
1957 | tty_lock(tty); | ||
1941 | retval = tty_reopen(tty); | 1958 | retval = tty_reopen(tty); |
1942 | if (retval) | 1959 | if (retval < 0) { |
1960 | tty_unlock(tty); | ||
1943 | tty = ERR_PTR(retval); | 1961 | tty = ERR_PTR(retval); |
1944 | } else | 1962 | } |
1963 | } else /* Returns with the tty_lock held for now */ | ||
1945 | tty = tty_init_dev(driver, index); | 1964 | tty = tty_init_dev(driver, index); |
1946 | 1965 | ||
1947 | mutex_unlock(&tty_mutex); | 1966 | mutex_unlock(&tty_mutex); |
1948 | if (driver) | 1967 | if (driver) |
1949 | tty_driver_kref_put(driver); | 1968 | tty_driver_kref_put(driver); |
1950 | if (IS_ERR(tty)) { | 1969 | if (IS_ERR(tty)) { |
1951 | tty_unlock(); | ||
1952 | retval = PTR_ERR(tty); | 1970 | retval = PTR_ERR(tty); |
1953 | goto err_file; | 1971 | goto err_file; |
1954 | } | 1972 | } |
@@ -1977,7 +1995,7 @@ retry_open: | |||
1977 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, | 1995 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, |
1978 | retval, tty->name); | 1996 | retval, tty->name); |
1979 | #endif | 1997 | #endif |
1980 | tty_unlock(); /* need to call tty_release without BTM */ | 1998 | tty_unlock(tty); /* need to call tty_release without BTM */ |
1981 | tty_release(inode, filp); | 1999 | tty_release(inode, filp); |
1982 | if (retval != -ERESTARTSYS) | 2000 | if (retval != -ERESTARTSYS) |
1983 | return retval; | 2001 | return retval; |
@@ -1989,17 +2007,15 @@ retry_open: | |||
1989 | /* | 2007 | /* |
1990 | * Need to reset f_op in case a hangup happened. | 2008 | * Need to reset f_op in case a hangup happened. |
1991 | */ | 2009 | */ |
1992 | tty_lock(); | ||
1993 | if (filp->f_op == &hung_up_tty_fops) | 2010 | if (filp->f_op == &hung_up_tty_fops) |
1994 | filp->f_op = &tty_fops; | 2011 | filp->f_op = &tty_fops; |
1995 | tty_unlock(); | ||
1996 | goto retry_open; | 2012 | goto retry_open; |
1997 | } | 2013 | } |
1998 | tty_unlock(); | 2014 | tty_unlock(tty); |
1999 | 2015 | ||
2000 | 2016 | ||
2001 | mutex_lock(&tty_mutex); | 2017 | mutex_lock(&tty_mutex); |
2002 | tty_lock(); | 2018 | tty_lock(tty); |
2003 | spin_lock_irq(¤t->sighand->siglock); | 2019 | spin_lock_irq(¤t->sighand->siglock); |
2004 | if (!noctty && | 2020 | if (!noctty && |
2005 | current->signal->leader && | 2021 | current->signal->leader && |
@@ -2007,11 +2023,10 @@ retry_open: | |||
2007 | tty->session == NULL) | 2023 | tty->session == NULL) |
2008 | __proc_set_tty(current, tty); | 2024 | __proc_set_tty(current, tty); |
2009 | spin_unlock_irq(¤t->sighand->siglock); | 2025 | spin_unlock_irq(¤t->sighand->siglock); |
2010 | tty_unlock(); | 2026 | tty_unlock(tty); |
2011 | mutex_unlock(&tty_mutex); | 2027 | mutex_unlock(&tty_mutex); |
2012 | return 0; | 2028 | return 0; |
2013 | err_unlock: | 2029 | err_unlock: |
2014 | tty_unlock(); | ||
2015 | mutex_unlock(&tty_mutex); | 2030 | mutex_unlock(&tty_mutex); |
2016 | /* after locks to avoid deadlock */ | 2031 | /* after locks to avoid deadlock */ |
2017 | if (!IS_ERR_OR_NULL(driver)) | 2032 | if (!IS_ERR_OR_NULL(driver)) |
@@ -2094,10 +2109,13 @@ out: | |||
2094 | 2109 | ||
2095 | static int tty_fasync(int fd, struct file *filp, int on) | 2110 | static int tty_fasync(int fd, struct file *filp, int on) |
2096 | { | 2111 | { |
2112 | struct tty_struct *tty = file_tty(filp); | ||
2097 | int retval; | 2113 | int retval; |
2098 | tty_lock(); | 2114 | |
2115 | tty_lock(tty); | ||
2099 | retval = __tty_fasync(fd, filp, on); | 2116 | retval = __tty_fasync(fd, filp, on); |
2100 | tty_unlock(); | 2117 | tty_unlock(tty); |
2118 | |||
2101 | return retval; | 2119 | return retval; |
2102 | } | 2120 | } |
2103 | 2121 | ||
@@ -2756,7 +2774,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2756 | if (ld->ops->ioctl) { | 2774 | if (ld->ops->ioctl) { |
2757 | retval = ld->ops->ioctl(tty, file, cmd, arg); | 2775 | retval = ld->ops->ioctl(tty, file, cmd, arg); |
2758 | if (retval == -ENOIOCTLCMD) | 2776 | if (retval == -ENOIOCTLCMD) |
2759 | retval = -EINVAL; | 2777 | retval = -ENOTTY; |
2760 | } | 2778 | } |
2761 | tty_ldisc_deref(ld); | 2779 | tty_ldisc_deref(ld); |
2762 | return retval; | 2780 | return retval; |
@@ -2934,6 +2952,7 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2934 | tty->pgrp = NULL; | 2952 | tty->pgrp = NULL; |
2935 | tty->overrun_time = jiffies; | 2953 | tty->overrun_time = jiffies; |
2936 | tty_buffer_init(tty); | 2954 | tty_buffer_init(tty); |
2955 | mutex_init(&tty->legacy_mutex); | ||
2937 | mutex_init(&tty->termios_mutex); | 2956 | mutex_init(&tty->termios_mutex); |
2938 | mutex_init(&tty->ldisc_mutex); | 2957 | mutex_init(&tty->ldisc_mutex); |
2939 | init_waitqueue_head(&tty->write_wait); | 2958 | init_waitqueue_head(&tty->write_wait); |
@@ -2991,6 +3010,15 @@ EXPORT_SYMBOL_GPL(tty_put_char); | |||
2991 | 3010 | ||
2992 | struct class *tty_class; | 3011 | struct class *tty_class; |
2993 | 3012 | ||
3013 | static int tty_cdev_add(struct tty_driver *driver, dev_t dev, | ||
3014 | unsigned int index, unsigned int count) | ||
3015 | { | ||
3016 | /* init here, since reused cdevs cause crashes */ | ||
3017 | cdev_init(&driver->cdevs[index], &tty_fops); | ||
3018 | driver->cdevs[index].owner = driver->owner; | ||
3019 | return cdev_add(&driver->cdevs[index], dev, count); | ||
3020 | } | ||
3021 | |||
2994 | /** | 3022 | /** |
2995 | * tty_register_device - register a tty device | 3023 | * tty_register_device - register a tty device |
2996 | * @driver: the tty driver that describes the tty device | 3024 | * @driver: the tty driver that describes the tty device |
@@ -3013,8 +3041,46 @@ struct class *tty_class; | |||
3013 | struct device *tty_register_device(struct tty_driver *driver, unsigned index, | 3041 | struct device *tty_register_device(struct tty_driver *driver, unsigned index, |
3014 | struct device *device) | 3042 | struct device *device) |
3015 | { | 3043 | { |
3044 | return tty_register_device_attr(driver, index, device, NULL, NULL); | ||
3045 | } | ||
3046 | EXPORT_SYMBOL(tty_register_device); | ||
3047 | |||
3048 | static void tty_device_create_release(struct device *dev) | ||
3049 | { | ||
3050 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); | ||
3051 | kfree(dev); | ||
3052 | } | ||
3053 | |||
3054 | /** | ||
3055 | * tty_register_device_attr - register a tty device | ||
3056 | * @driver: the tty driver that describes the tty device | ||
3057 | * @index: the index in the tty driver for this tty device | ||
3058 | * @device: a struct device that is associated with this tty device. | ||
3059 | * This field is optional, if there is no known struct device | ||
3060 | * for this tty device it can be set to NULL safely. | ||
3061 | * @drvdata: Driver data to be set to device. | ||
3062 | * @attr_grp: Attribute group to be set on device. | ||
3063 | * | ||
3064 | * Returns a pointer to the struct device for this tty device | ||
3065 | * (or ERR_PTR(-EFOO) on error). | ||
3066 | * | ||
3067 | * This call is required to be made to register an individual tty device | ||
3068 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If | ||
3069 | * that bit is not set, this function should not be called by a tty | ||
3070 | * driver. | ||
3071 | * | ||
3072 | * Locking: ?? | ||
3073 | */ | ||
3074 | struct device *tty_register_device_attr(struct tty_driver *driver, | ||
3075 | unsigned index, struct device *device, | ||
3076 | void *drvdata, | ||
3077 | const struct attribute_group **attr_grp) | ||
3078 | { | ||
3016 | char name[64]; | 3079 | char name[64]; |
3017 | dev_t dev = MKDEV(driver->major, driver->minor_start) + index; | 3080 | dev_t devt = MKDEV(driver->major, driver->minor_start) + index; |
3081 | struct device *dev = NULL; | ||
3082 | int retval = -ENODEV; | ||
3083 | bool cdev = false; | ||
3018 | 3084 | ||
3019 | if (index >= driver->num) { | 3085 | if (index >= driver->num) { |
3020 | printk(KERN_ERR "Attempt to register invalid tty line number " | 3086 | printk(KERN_ERR "Attempt to register invalid tty line number " |
@@ -3027,9 +3093,40 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index, | |||
3027 | else | 3093 | else |
3028 | tty_line_name(driver, index, name); | 3094 | tty_line_name(driver, index, name); |
3029 | 3095 | ||
3030 | return device_create(tty_class, device, dev, NULL, name); | 3096 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) { |
3097 | retval = tty_cdev_add(driver, devt, index, 1); | ||
3098 | if (retval) | ||
3099 | goto error; | ||
3100 | cdev = true; | ||
3101 | } | ||
3102 | |||
3103 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
3104 | if (!dev) { | ||
3105 | retval = -ENOMEM; | ||
3106 | goto error; | ||
3107 | } | ||
3108 | |||
3109 | dev->devt = devt; | ||
3110 | dev->class = tty_class; | ||
3111 | dev->parent = device; | ||
3112 | dev->release = tty_device_create_release; | ||
3113 | dev_set_name(dev, "%s", name); | ||
3114 | dev->groups = attr_grp; | ||
3115 | dev_set_drvdata(dev, drvdata); | ||
3116 | |||
3117 | retval = device_register(dev); | ||
3118 | if (retval) | ||
3119 | goto error; | ||
3120 | |||
3121 | return dev; | ||
3122 | |||
3123 | error: | ||
3124 | put_device(dev); | ||
3125 | if (cdev) | ||
3126 | cdev_del(&driver->cdevs[index]); | ||
3127 | return ERR_PTR(retval); | ||
3031 | } | 3128 | } |
3032 | EXPORT_SYMBOL(tty_register_device); | 3129 | EXPORT_SYMBOL_GPL(tty_register_device_attr); |
3033 | 3130 | ||
3034 | /** | 3131 | /** |
3035 | * tty_unregister_device - unregister a tty device | 3132 | * tty_unregister_device - unregister a tty device |
@@ -3046,31 +3143,82 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) | |||
3046 | { | 3143 | { |
3047 | device_destroy(tty_class, | 3144 | device_destroy(tty_class, |
3048 | MKDEV(driver->major, driver->minor_start) + index); | 3145 | MKDEV(driver->major, driver->minor_start) + index); |
3146 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) | ||
3147 | cdev_del(&driver->cdevs[index]); | ||
3049 | } | 3148 | } |
3050 | EXPORT_SYMBOL(tty_unregister_device); | 3149 | EXPORT_SYMBOL(tty_unregister_device); |
3051 | 3150 | ||
3052 | struct tty_driver *__alloc_tty_driver(int lines, struct module *owner) | 3151 | /** |
3152 | * __tty_alloc_driver -- allocate tty driver | ||
3153 | * @lines: count of lines this driver can handle at most | ||
3154 | * @owner: module which is repsonsible for this driver | ||
3155 | * @flags: some of TTY_DRIVER_* flags, will be set in driver->flags | ||
3156 | * | ||
3157 | * This should not be called directly, some of the provided macros should be | ||
3158 | * used instead. Use IS_ERR and friends on @retval. | ||
3159 | */ | ||
3160 | struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, | ||
3161 | unsigned long flags) | ||
3053 | { | 3162 | { |
3054 | struct tty_driver *driver; | 3163 | struct tty_driver *driver; |
3164 | unsigned int cdevs = 1; | ||
3165 | int err; | ||
3166 | |||
3167 | if (!lines || (flags & TTY_DRIVER_UNNUMBERED_NODE && lines > 1)) | ||
3168 | return ERR_PTR(-EINVAL); | ||
3055 | 3169 | ||
3056 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); | 3170 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); |
3057 | if (driver) { | 3171 | if (!driver) |
3058 | kref_init(&driver->kref); | 3172 | return ERR_PTR(-ENOMEM); |
3059 | driver->magic = TTY_DRIVER_MAGIC; | 3173 | |
3060 | driver->num = lines; | 3174 | kref_init(&driver->kref); |
3061 | driver->owner = owner; | 3175 | driver->magic = TTY_DRIVER_MAGIC; |
3062 | /* later we'll move allocation of tables here */ | 3176 | driver->num = lines; |
3177 | driver->owner = owner; | ||
3178 | driver->flags = flags; | ||
3179 | |||
3180 | if (!(flags & TTY_DRIVER_DEVPTS_MEM)) { | ||
3181 | driver->ttys = kcalloc(lines, sizeof(*driver->ttys), | ||
3182 | GFP_KERNEL); | ||
3183 | driver->termios = kcalloc(lines, sizeof(*driver->termios), | ||
3184 | GFP_KERNEL); | ||
3185 | if (!driver->ttys || !driver->termios) { | ||
3186 | err = -ENOMEM; | ||
3187 | goto err_free_all; | ||
3188 | } | ||
3063 | } | 3189 | } |
3190 | |||
3191 | if (!(flags & TTY_DRIVER_DYNAMIC_ALLOC)) { | ||
3192 | driver->ports = kcalloc(lines, sizeof(*driver->ports), | ||
3193 | GFP_KERNEL); | ||
3194 | if (!driver->ports) { | ||
3195 | err = -ENOMEM; | ||
3196 | goto err_free_all; | ||
3197 | } | ||
3198 | cdevs = lines; | ||
3199 | } | ||
3200 | |||
3201 | driver->cdevs = kcalloc(cdevs, sizeof(*driver->cdevs), GFP_KERNEL); | ||
3202 | if (!driver->cdevs) { | ||
3203 | err = -ENOMEM; | ||
3204 | goto err_free_all; | ||
3205 | } | ||
3206 | |||
3064 | return driver; | 3207 | return driver; |
3208 | err_free_all: | ||
3209 | kfree(driver->ports); | ||
3210 | kfree(driver->ttys); | ||
3211 | kfree(driver->termios); | ||
3212 | kfree(driver); | ||
3213 | return ERR_PTR(err); | ||
3065 | } | 3214 | } |
3066 | EXPORT_SYMBOL(__alloc_tty_driver); | 3215 | EXPORT_SYMBOL(__tty_alloc_driver); |
3067 | 3216 | ||
3068 | static void destruct_tty_driver(struct kref *kref) | 3217 | static void destruct_tty_driver(struct kref *kref) |
3069 | { | 3218 | { |
3070 | struct tty_driver *driver = container_of(kref, struct tty_driver, kref); | 3219 | struct tty_driver *driver = container_of(kref, struct tty_driver, kref); |
3071 | int i; | 3220 | int i; |
3072 | struct ktermios *tp; | 3221 | struct ktermios *tp; |
3073 | void *p; | ||
3074 | 3222 | ||
3075 | if (driver->flags & TTY_DRIVER_INSTALLED) { | 3223 | if (driver->flags & TTY_DRIVER_INSTALLED) { |
3076 | /* | 3224 | /* |
@@ -3087,13 +3235,14 @@ static void destruct_tty_driver(struct kref *kref) | |||
3087 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) | 3235 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) |
3088 | tty_unregister_device(driver, i); | 3236 | tty_unregister_device(driver, i); |
3089 | } | 3237 | } |
3090 | p = driver->ttys; | ||
3091 | proc_tty_unregister_driver(driver); | 3238 | proc_tty_unregister_driver(driver); |
3092 | driver->ttys = NULL; | 3239 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) |
3093 | driver->termios = NULL; | 3240 | cdev_del(&driver->cdevs[0]); |
3094 | kfree(p); | ||
3095 | cdev_del(&driver->cdev); | ||
3096 | } | 3241 | } |
3242 | kfree(driver->cdevs); | ||
3243 | kfree(driver->ports); | ||
3244 | kfree(driver->termios); | ||
3245 | kfree(driver->ttys); | ||
3097 | kfree(driver); | 3246 | kfree(driver); |
3098 | } | 3247 | } |
3099 | 3248 | ||
@@ -3124,15 +3273,8 @@ int tty_register_driver(struct tty_driver *driver) | |||
3124 | int error; | 3273 | int error; |
3125 | int i; | 3274 | int i; |
3126 | dev_t dev; | 3275 | dev_t dev; |
3127 | void **p = NULL; | ||
3128 | struct device *d; | 3276 | struct device *d; |
3129 | 3277 | ||
3130 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { | ||
3131 | p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); | ||
3132 | if (!p) | ||
3133 | return -ENOMEM; | ||
3134 | } | ||
3135 | |||
3136 | if (!driver->major) { | 3278 | if (!driver->major) { |
3137 | error = alloc_chrdev_region(&dev, driver->minor_start, | 3279 | error = alloc_chrdev_region(&dev, driver->minor_start, |
3138 | driver->num, driver->name); | 3280 | driver->num, driver->name); |
@@ -3144,28 +3286,13 @@ int tty_register_driver(struct tty_driver *driver) | |||
3144 | dev = MKDEV(driver->major, driver->minor_start); | 3286 | dev = MKDEV(driver->major, driver->minor_start); |
3145 | error = register_chrdev_region(dev, driver->num, driver->name); | 3287 | error = register_chrdev_region(dev, driver->num, driver->name); |
3146 | } | 3288 | } |
3147 | if (error < 0) { | 3289 | if (error < 0) |
3148 | kfree(p); | 3290 | goto err; |
3149 | return error; | ||
3150 | } | ||
3151 | 3291 | ||
3152 | if (p) { | 3292 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) { |
3153 | driver->ttys = (struct tty_struct **)p; | 3293 | error = tty_cdev_add(driver, dev, 0, driver->num); |
3154 | driver->termios = (struct ktermios **)(p + driver->num); | 3294 | if (error) |
3155 | } else { | 3295 | goto err_unreg_char; |
3156 | driver->ttys = NULL; | ||
3157 | driver->termios = NULL; | ||
3158 | } | ||
3159 | |||
3160 | cdev_init(&driver->cdev, &tty_fops); | ||
3161 | driver->cdev.owner = driver->owner; | ||
3162 | error = cdev_add(&driver->cdev, dev, driver->num); | ||
3163 | if (error) { | ||
3164 | unregister_chrdev_region(dev, driver->num); | ||
3165 | driver->ttys = NULL; | ||
3166 | driver->termios = NULL; | ||
3167 | kfree(p); | ||
3168 | return error; | ||
3169 | } | 3296 | } |
3170 | 3297 | ||
3171 | mutex_lock(&tty_mutex); | 3298 | mutex_lock(&tty_mutex); |
@@ -3177,7 +3304,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
3177 | d = tty_register_device(driver, i, NULL); | 3304 | d = tty_register_device(driver, i, NULL); |
3178 | if (IS_ERR(d)) { | 3305 | if (IS_ERR(d)) { |
3179 | error = PTR_ERR(d); | 3306 | error = PTR_ERR(d); |
3180 | goto err; | 3307 | goto err_unreg_devs; |
3181 | } | 3308 | } |
3182 | } | 3309 | } |
3183 | } | 3310 | } |
@@ -3185,7 +3312,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
3185 | driver->flags |= TTY_DRIVER_INSTALLED; | 3312 | driver->flags |= TTY_DRIVER_INSTALLED; |
3186 | return 0; | 3313 | return 0; |
3187 | 3314 | ||
3188 | err: | 3315 | err_unreg_devs: |
3189 | for (i--; i >= 0; i--) | 3316 | for (i--; i >= 0; i--) |
3190 | tty_unregister_device(driver, i); | 3317 | tty_unregister_device(driver, i); |
3191 | 3318 | ||
@@ -3193,13 +3320,11 @@ err: | |||
3193 | list_del(&driver->tty_drivers); | 3320 | list_del(&driver->tty_drivers); |
3194 | mutex_unlock(&tty_mutex); | 3321 | mutex_unlock(&tty_mutex); |
3195 | 3322 | ||
3323 | err_unreg_char: | ||
3196 | unregister_chrdev_region(dev, driver->num); | 3324 | unregister_chrdev_region(dev, driver->num); |
3197 | driver->ttys = NULL; | 3325 | err: |
3198 | driver->termios = NULL; | ||
3199 | kfree(p); | ||
3200 | return error; | 3326 | return error; |
3201 | } | 3327 | } |
3202 | |||
3203 | EXPORT_SYMBOL(tty_register_driver); | 3328 | EXPORT_SYMBOL(tty_register_driver); |
3204 | 3329 | ||
3205 | /* | 3330 | /* |