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/tty/tty_io.c | |
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/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 56 |
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 | } |
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); |