diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/pty.c | 15 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 49 | ||||
-rw-r--r-- | drivers/char/vt.c | 34 |
3 files changed, 57 insertions, 41 deletions
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 76b27932d229..ec09c1cd4fe9 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -388,7 +388,14 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, | |||
388 | return -ENOIOCTLCMD; | 388 | return -ENOIOCTLCMD; |
389 | } | 389 | } |
390 | 390 | ||
391 | static const struct tty_operations pty_unix98_ops = { | 391 | static void pty_shutdown(struct tty_struct *tty) |
392 | { | ||
393 | /* We have our own method as we don't use the tty index */ | ||
394 | kfree(tty->termios); | ||
395 | kfree(tty->termios_locked); | ||
396 | } | ||
397 | |||
398 | static const struct tty_operations ptm_unix98_ops = { | ||
392 | .open = pty_open, | 399 | .open = pty_open, |
393 | .close = pty_close, | 400 | .close = pty_close, |
394 | .write = pty_write, | 401 | .write = pty_write, |
@@ -397,10 +404,10 @@ static const struct tty_operations pty_unix98_ops = { | |||
397 | .chars_in_buffer = pty_chars_in_buffer, | 404 | .chars_in_buffer = pty_chars_in_buffer, |
398 | .unthrottle = pty_unthrottle, | 405 | .unthrottle = pty_unthrottle, |
399 | .set_termios = pty_set_termios, | 406 | .set_termios = pty_set_termios, |
400 | .ioctl = pty_unix98_ioctl | 407 | .ioctl = pty_unix98_ioctl, |
408 | .shutdown = pty_shutdown | ||
401 | }; | 409 | }; |
402 | 410 | ||
403 | |||
404 | static void __init unix98_pty_init(void) | 411 | static void __init unix98_pty_init(void) |
405 | { | 412 | { |
406 | ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX); | 413 | ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX); |
@@ -427,7 +434,7 @@ static void __init unix98_pty_init(void) | |||
427 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | 434 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | |
428 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | 435 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; |
429 | ptm_driver->other = pts_driver; | 436 | ptm_driver->other = pts_driver; |
430 | tty_set_operations(ptm_driver, &pty_unix98_ops); | 437 | tty_set_operations(ptm_driver, &ptm_unix98_ops); |
431 | 438 | ||
432 | pts_driver->owner = THIS_MODULE; | 439 | pts_driver->owner = THIS_MODULE; |
433 | pts_driver->driver_name = "pty_slave"; | 440 | pts_driver->driver_name = "pty_slave"; |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 2e96ce0fddc5..f91704d57a4e 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1482,6 +1482,31 @@ release_mem_out: | |||
1482 | goto end_init; | 1482 | goto end_init; |
1483 | } | 1483 | } |
1484 | 1484 | ||
1485 | void tty_free_termios(struct tty_struct *tty) | ||
1486 | { | ||
1487 | struct ktermios *tp; | ||
1488 | int idx = tty->index; | ||
1489 | /* Kill this flag and push into drivers for locking etc */ | ||
1490 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | ||
1491 | /* FIXME: Locking on ->termios array */ | ||
1492 | tp = tty->termios; | ||
1493 | tty->driver->termios[idx] = NULL; | ||
1494 | kfree(tp); | ||
1495 | |||
1496 | tp = tty->termios_locked; | ||
1497 | tty->driver->termios_locked[idx] = NULL; | ||
1498 | kfree(tp); | ||
1499 | } | ||
1500 | } | ||
1501 | EXPORT_SYMBOL(tty_free_termios); | ||
1502 | |||
1503 | void tty_shutdown(struct tty_struct *tty) | ||
1504 | { | ||
1505 | tty->driver->ttys[tty->index] = NULL; | ||
1506 | tty_free_termios(tty); | ||
1507 | } | ||
1508 | EXPORT_SYMBOL(tty_shutdown); | ||
1509 | |||
1485 | /** | 1510 | /** |
1486 | * release_one_tty - release tty structure memory | 1511 | * release_one_tty - release tty structure memory |
1487 | * @kref: kref of tty we are obliterating | 1512 | * @kref: kref of tty we are obliterating |
@@ -1499,27 +1524,11 @@ static void release_one_tty(struct kref *kref) | |||
1499 | { | 1524 | { |
1500 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); | 1525 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
1501 | struct tty_driver *driver = tty->driver; | 1526 | struct tty_driver *driver = tty->driver; |
1502 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; | ||
1503 | struct ktermios *tp; | ||
1504 | int idx = tty->index; | ||
1505 | |||
1506 | if (!devpts) | ||
1507 | tty->driver->ttys[idx] = NULL; | ||
1508 | |||
1509 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | ||
1510 | /* FIXME: Locking on ->termios array */ | ||
1511 | tp = tty->termios; | ||
1512 | if (!devpts) | ||
1513 | tty->driver->termios[idx] = NULL; | ||
1514 | kfree(tp); | ||
1515 | |||
1516 | tp = tty->termios_locked; | ||
1517 | if (!devpts) | ||
1518 | tty->driver->termios_locked[idx] = NULL; | ||
1519 | kfree(tp); | ||
1520 | } | ||
1521 | |||
1522 | 1527 | ||
1528 | if (tty->ops->shutdown) | ||
1529 | tty->ops->shutdown(tty); | ||
1530 | else | ||
1531 | tty_shutdown(tty); | ||
1523 | tty->magic = 0; | 1532 | tty->magic = 0; |
1524 | /* FIXME: locking on tty->driver->refcount */ | 1533 | /* FIXME: locking on tty->driver->refcount */ |
1525 | tty->driver->refcount--; | 1534 | tty->driver->refcount--; |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index ec94521c3118..37a45db5bae0 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -2758,6 +2758,12 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2758 | ret = vc_allocate(currcons); | 2758 | ret = vc_allocate(currcons); |
2759 | if (ret == 0) { | 2759 | if (ret == 0) { |
2760 | struct vc_data *vc = vc_cons[currcons].d; | 2760 | struct vc_data *vc = vc_cons[currcons].d; |
2761 | |||
2762 | /* Still being freed */ | ||
2763 | if (vc->vc_tty) { | ||
2764 | release_console_sem(); | ||
2765 | return -ERESTARTSYS; | ||
2766 | } | ||
2761 | tty->driver_data = vc; | 2767 | tty->driver_data = vc; |
2762 | vc->vc_tty = tty; | 2768 | vc->vc_tty = tty; |
2763 | 2769 | ||
@@ -2787,25 +2793,18 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2787 | */ | 2793 | */ |
2788 | static void con_close(struct tty_struct *tty, struct file *filp) | 2794 | static void con_close(struct tty_struct *tty, struct file *filp) |
2789 | { | 2795 | { |
2790 | mutex_lock(&tty_mutex); | 2796 | /* Nothing to do - we defer to shutdown */ |
2791 | acquire_console_sem(); | 2797 | } |
2792 | if (tty && tty->count == 1) { | ||
2793 | struct vc_data *vc = tty->driver_data; | ||
2794 | 2798 | ||
2795 | if (vc) | 2799 | static void con_shutdown(struct tty_struct *tty) |
2796 | vc->vc_tty = NULL; | 2800 | { |
2797 | tty->driver_data = NULL; | 2801 | struct vc_data *vc = tty->driver_data; |
2798 | vcs_remove_sysfs(tty); | 2802 | BUG_ON(vc == NULL); |
2799 | release_console_sem(); | 2803 | acquire_console_sem(); |
2800 | mutex_unlock(&tty_mutex); | 2804 | vc->vc_tty = NULL; |
2801 | /* | 2805 | vcs_remove_sysfs(tty); |
2802 | * tty_mutex is released, but we still hold BKL, so there is | ||
2803 | * still exclusion against init_dev() | ||
2804 | */ | ||
2805 | return; | ||
2806 | } | ||
2807 | release_console_sem(); | 2806 | release_console_sem(); |
2808 | mutex_unlock(&tty_mutex); | 2807 | tty_shutdown(tty); |
2809 | } | 2808 | } |
2810 | 2809 | ||
2811 | static int default_italic_color = 2; // green (ASCII) | 2810 | static int default_italic_color = 2; // green (ASCII) |
@@ -2930,6 +2929,7 @@ static const struct tty_operations con_ops = { | |||
2930 | .throttle = con_throttle, | 2929 | .throttle = con_throttle, |
2931 | .unthrottle = con_unthrottle, | 2930 | .unthrottle = con_unthrottle, |
2932 | .resize = vt_resize, | 2931 | .resize = vt_resize, |
2932 | .shutdown = con_shutdown | ||
2933 | }; | 2933 | }; |
2934 | 2934 | ||
2935 | int __init vty_init(void) | 2935 | int __init vty_init(void) |