aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2012-07-17 12:06:57 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-17 12:13:38 -0400
commit36b3c070d2346c890d690d71f6eab02f8c511137 (patch)
tree1a1345329e3827eec3cf0de70eac2b2f1d663b55 /drivers
parent3db1ddb725dcd9a2bb32be2b64d0688c3e1c4579 (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.c12
-rw-r--r--drivers/tty/tty_io.c56
-rw-r--r--drivers/tty/vt/vt.c1
-rw-r--r--drivers/usb/serial/usb-serial.c3
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
530static 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
566static const struct tty_operations pty_unix98_ops = { 559static 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}
1450EXPORT_SYMBOL(tty_free_termios); 1456EXPORT_SYMBOL(tty_free_termios);
1451 1457
1452void tty_shutdown(struct tty_struct *tty)
1453{
1454 tty_driver_remove_tty(tty->driver, tty);
1455 tty_free_termios(tty);
1456}
1457EXPORT_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
2856static int default_italic_color = 2; // green (ASCII) 2855static 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 */
311static void serial_cleanup(struct tty_struct *tty) 310static void serial_cleanup(struct tty_struct *tty)
312{ 311{