aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_io.c
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/tty/tty_io.c
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/tty/tty_io.c')
-rw-r--r--drivers/tty/tty_io.c56
1 files changed, 28 insertions, 28 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index cfd12da81218..be18d60ddf4c 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);