diff options
author | Alan Cox <alan@linux.intel.com> | 2012-07-17 12:06:57 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-07-17 12:13:38 -0400 |
commit | 36b3c070d2346c890d690d71f6eab02f8c511137 (patch) | |
tree | 1a1345329e3827eec3cf0de70eac2b2f1d663b55 /drivers | |
parent | 3db1ddb725dcd9a2bb32be2b64d0688c3e1c4579 (diff) |
tty: Move the handling of the tty release logic
Now that we don't have tty->termios tied to drivers->tty we can untangle
the logic here. In addition we can push the removal logic out of the
destructor path.
At that point we can think about sorting out tty_port and console and all
the other ugly hangovers.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/tty/pty.c | 12 | ||||
-rw-r--r-- | drivers/tty/tty_io.c | 56 | ||||
-rw-r--r-- | drivers/tty/vt/vt.c | 1 | ||||
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 3 |
4 files changed, 31 insertions, 41 deletions
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 5ad7ccc49f7..60c08ce8378 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -527,12 +527,6 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, | |||
527 | return tty; | 527 | return tty; |
528 | } | 528 | } |
529 | 529 | ||
530 | static void pty_unix98_shutdown(struct tty_struct *tty) | ||
531 | { | ||
532 | tty_driver_remove_tty(tty->driver, tty); | ||
533 | /* We have our own method as we don't use the tty index */ | ||
534 | } | ||
535 | |||
536 | /* We have no need to install and remove our tty objects as devpts does all | 530 | /* We have no need to install and remove our tty objects as devpts does all |
537 | the work for us */ | 531 | the work for us */ |
538 | 532 | ||
@@ -558,9 +552,8 @@ static const struct tty_operations ptm_unix98_ops = { | |||
558 | .unthrottle = pty_unthrottle, | 552 | .unthrottle = pty_unthrottle, |
559 | .set_termios = pty_set_termios, | 553 | .set_termios = pty_set_termios, |
560 | .ioctl = pty_unix98_ioctl, | 554 | .ioctl = pty_unix98_ioctl, |
561 | .shutdown = pty_unix98_shutdown, | 555 | .resize = pty_resize, |
562 | .cleanup = pty_cleanup, | 556 | .cleanup = pty_cleanup |
563 | .resize = pty_resize | ||
564 | }; | 557 | }; |
565 | 558 | ||
566 | static const struct tty_operations pty_unix98_ops = { | 559 | static const struct tty_operations pty_unix98_ops = { |
@@ -575,7 +568,6 @@ static const struct tty_operations pty_unix98_ops = { | |||
575 | .chars_in_buffer = pty_chars_in_buffer, | 568 | .chars_in_buffer = pty_chars_in_buffer, |
576 | .unthrottle = pty_unthrottle, | 569 | .unthrottle = pty_unthrottle, |
577 | .set_termios = pty_set_termios, | 570 | .set_termios = pty_set_termios, |
578 | .shutdown = pty_unix98_shutdown, | ||
579 | .cleanup = pty_cleanup, | 571 | .cleanup = pty_cleanup, |
580 | }; | 572 | }; |
581 | 573 | ||
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index cfd12da8121..be18d60ddf4 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -1249,16 +1249,16 @@ int tty_init_termios(struct tty_struct *tty) | |||
1249 | struct ktermios *tp; | 1249 | struct ktermios *tp; |
1250 | int idx = tty->index; | 1250 | int idx = tty->index; |
1251 | 1251 | ||
1252 | tp = tty->driver->termios[idx]; | 1252 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
1253 | if (tp == NULL) { | 1253 | tty->termios = tty->driver->init_termios; |
1254 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | 1254 | else { |
1255 | if (tp == NULL) | 1255 | /* Check for lazy saved data */ |
1256 | return -ENOMEM; | 1256 | tp = tty->driver->termios[idx]; |
1257 | *tp = tty->driver->init_termios; | 1257 | if (tp != NULL) |
1258 | tty->driver->termios[idx] = tp; | 1258 | tty->termios = *tp; |
1259 | else | ||
1260 | tty->termios = tty->driver->init_termios; | ||
1259 | } | 1261 | } |
1260 | tty->termios = *tp; | ||
1261 | |||
1262 | /* Compatibility until drivers always set this */ | 1262 | /* Compatibility until drivers always set this */ |
1263 | tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); | 1263 | tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); |
1264 | tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); | 1264 | tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); |
@@ -1437,24 +1437,24 @@ void tty_free_termios(struct tty_struct *tty) | |||
1437 | { | 1437 | { |
1438 | struct ktermios *tp; | 1438 | struct ktermios *tp; |
1439 | int idx = tty->index; | 1439 | int idx = tty->index; |
1440 | /* Kill this flag and push into drivers for locking etc */ | 1440 | |
1441 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | 1441 | /* If the port is going to reset then it has no termios to save */ |
1442 | /* FIXME: Locking on ->termios array */ | 1442 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
1443 | tp = tty->driver->termios[idx]; | 1443 | return; |
1444 | tty->driver->termios[idx] = NULL; | 1444 | |
1445 | kfree(tp); | 1445 | /* Stash the termios data */ |
1446 | tp = tty->driver->termios[idx]; | ||
1447 | if (tp == NULL) { | ||
1448 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1449 | if (tp == NULL) { | ||
1450 | pr_warn("tty: no memory to save termios state.\n"); | ||
1451 | return; | ||
1452 | } | ||
1446 | } | 1453 | } |
1447 | else | 1454 | *tp = tty->termios; |
1448 | *tty->driver->termios[idx] = tty->termios; | ||
1449 | } | 1455 | } |
1450 | EXPORT_SYMBOL(tty_free_termios); | 1456 | EXPORT_SYMBOL(tty_free_termios); |
1451 | 1457 | ||
1452 | void tty_shutdown(struct tty_struct *tty) | ||
1453 | { | ||
1454 | tty_driver_remove_tty(tty->driver, tty); | ||
1455 | tty_free_termios(tty); | ||
1456 | } | ||
1457 | EXPORT_SYMBOL(tty_shutdown); | ||
1458 | 1458 | ||
1459 | /** | 1459 | /** |
1460 | * release_one_tty - release tty structure memory | 1460 | * release_one_tty - release tty structure memory |
@@ -1498,11 +1498,6 @@ static void queue_release_one_tty(struct kref *kref) | |||
1498 | { | 1498 | { |
1499 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); | 1499 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
1500 | 1500 | ||
1501 | if (tty->ops->shutdown) | ||
1502 | tty->ops->shutdown(tty); | ||
1503 | else | ||
1504 | tty_shutdown(tty); | ||
1505 | |||
1506 | /* The hangup queue is now free so we can reuse it rather than | 1501 | /* The hangup queue is now free so we can reuse it rather than |
1507 | waste a chunk of memory for each port */ | 1502 | waste a chunk of memory for each port */ |
1508 | INIT_WORK(&tty->hangup_work, release_one_tty); | 1503 | INIT_WORK(&tty->hangup_work, release_one_tty); |
@@ -1542,6 +1537,11 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1542 | /* This should always be true but check for the moment */ | 1537 | /* This should always be true but check for the moment */ |
1543 | WARN_ON(tty->index != idx); | 1538 | WARN_ON(tty->index != idx); |
1544 | 1539 | ||
1540 | if (tty->ops->shutdown) | ||
1541 | tty->ops->shutdown(tty); | ||
1542 | tty_free_termios(tty); | ||
1543 | tty_driver_remove_tty(tty->driver, tty); | ||
1544 | |||
1545 | if (tty->link) | 1545 | if (tty->link) |
1546 | tty_kref_put(tty->link); | 1546 | tty_kref_put(tty->link); |
1547 | tty_kref_put(tty); | 1547 | tty_kref_put(tty); |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index dbceaeb2c3e..e07ded30fc7 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -2850,7 +2850,6 @@ static void con_shutdown(struct tty_struct *tty) | |||
2850 | console_lock(); | 2850 | console_lock(); |
2851 | vc->port.tty = NULL; | 2851 | vc->port.tty = NULL; |
2852 | console_unlock(); | 2852 | console_unlock(); |
2853 | tty_shutdown(tty); | ||
2854 | } | 2853 | } |
2855 | 2854 | ||
2856 | static int default_italic_color = 2; // green (ASCII) | 2855 | static int default_italic_color = 2; // green (ASCII) |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 5fe21357b55..aa4b0d77599 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -305,8 +305,7 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
305 | * Do the resource freeing and refcount dropping for the port. | 305 | * Do the resource freeing and refcount dropping for the port. |
306 | * Avoid freeing the console. | 306 | * Avoid freeing the console. |
307 | * | 307 | * |
308 | * Called asynchronously after the last tty kref is dropped, | 308 | * Called asynchronously after the last tty kref is dropped. |
309 | * and the tty layer has already done the tty_shutdown(tty); | ||
310 | */ | 309 | */ |
311 | static void serial_cleanup(struct tty_struct *tty) | 310 | static void serial_cleanup(struct tty_struct *tty) |
312 | { | 311 | { |