Commit Graph

69 Commits

Author SHA1 Message Date
Lee Jones
1b1deb44d1 tty: tty_port: Demote obvious abuse of kernel-doc formatting
Fixes the following W=1 kernel build warning(s):

 drivers/tty/tty_port.c:633: warning: Function parameter or member 'port' not described in 'tty_port_close'
 drivers/tty/tty_port.c:633: warning: Function parameter or member 'tty' not described in 'tty_port_close'
 drivers/tty/tty_port.c:633: warning: Function parameter or member 'filp' not described in 'tty_port_close'
 drivers/tty/tty_port.c:672: warning: Function parameter or member 'port' not described in 'tty_port_open'
 drivers/tty/tty_port.c:672: warning: Function parameter or member 'tty' not described in 'tty_port_open'
 drivers/tty/tty_port.c:672: warning: Function parameter or member 'filp' not described in 'tty_port_open'

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jirislaby@kernel.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Link: https://lore.kernel.org/r/20201104193549.4026187-7-lee.jones@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-11-06 10:49:27 +01:00
Johan Hovold
0c5aae5927 serdev: ttyport: restore client ops on deregistration
The serdev tty-port controller driver should reset the tty-port client
operations also on deregistration to avoid a NULL-pointer dereference in
case the port is later re-registered as a normal tty device.

Note that this can only happen with tty drivers such as 8250 which have
statically allocated port structures that can end up being reused and
where a later registration would not register a serdev controller (e.g.
due to registration errors or if the devicetree has been changed in
between).

Specifically, this can be an issue for any statically defined ports that
would be registered by 8250 core when an 8250 driver is being unbound.

Fixes: bed35c6dfa ("serdev: add a tty port controller driver")
Cc: stable <stable@vger.kernel.org>     # 4.11
Reported-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://lore.kernel.org/r/20200210145730.22762-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-02-10 12:26:44 -08:00
Sudip Mukherjee
273f632912 tty: always relink the port
If the serial device is disconnected and reconnected, it re-enumerates
properly but does not link it. fwiw, linking means just saving the port
index, so allow it always as there is no harm in saving the same value
again even if it tries to relink with the same port.

Fixes: fb2b90014d ("tty: link tty and port before configuring it as console")
Reported-by: Kenneth R. Crudup <kenny@panix.com>
Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
Cc: stable <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20191227174434.12057-1-sudipm.mukherjee@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-12-30 19:34:44 +01:00
Sudip Mukherjee
fb2b90014d tty: link tty and port before configuring it as console
There seems to be a race condition in tty drivers and I could see on
many boot cycles a NULL pointer dereference as tty_init_dev() tries to
do 'tty->port->itty = tty' even though tty->port is NULL.
'tty->port' will be set by the driver and if the driver has not yet done
it before we open the tty device we can get to this situation. By adding
some extra debug prints, I noticed that:

6.650130: uart_add_one_port
6.663849: register_console
6.664846: tty_open
6.674391: tty_init_dev
6.675456: tty_port_link_device

uart_add_one_port() registers the console, as soon as it registers, the
userspace tries to use it and that leads to tty_open() but
uart_add_one_port() has not yet done tty_port_link_device() and so
tty->port is not yet configured when control reaches tty_init_dev().

Further look into the code and tty_port_link_device() is done by
uart_add_one_port(). After registering the console uart_add_one_port()
will call tty_port_register_device_attr_serdev() and
tty_port_link_device() is called from this.

Call add tty_port_link_device() before uart_configure_port() is done and
add a check in tty_port_link_device() so that it only links the port if
it has not been done yet.

Suggested-by: Jiri Slaby <jslaby@suse.com>
Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
Cc: stable <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20191212131602.29504-1-sudipm.mukherjee@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-12-17 14:12:34 +01:00
Johan Hovold
0d3cb6f6c6 Revert "tty: fix NULL pointer issue when tty_port ops is not set"
This reverts commit f4e68d58cf.

TTY drivers using the tty-port abstraction all provide a pointer to a
set of port operations, which specifically cannot be NULL (or we'd find
out at first attempt to open a port).

Revert the recent commit which added unnecessary NULL-checks and whose
commit message indicated that it was fixing a real problem, which it did
not.

Note that even the two tty drivers for virtual devices currently
providing an empty set of operations probably should be implementing at
least some of the callbacks.

Cc: Fabien Dessenne <fabien.dessenne@st.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-04-16 15:21:34 +02:00
Fabien Dessenne
f4e68d58cf tty: fix NULL pointer issue when tty_port ops is not set
Unlike 'client_ops' which is initialized to 'default_client_ops', the
port operations 'ops' may be left to NULL.
Check the 'ops' value before checking the 'ops->x' value.

Signed-off-by: Fabien Dessenne <fabien.dessenne@st.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-03-28 01:21:21 +09:00
Chanho Park
2a48602615 tty: do not set TTY_IO_ERROR flag if console port
Since Commit 761ed4a945 ('tty: serial_core: convert uart_close to use
tty_port_close') and Commit 4dda864d73 ('tty: serial_core: Fix serial
console crash on port shutdown), a serial port which is used as
console can be stuck when logging out if there is a remained process.
After logged out, agetty will try to grab the serial port but it will
be failed because the previous process did not release the port
correctly. To fix this, TTY_IO_ERROR bit should not be enabled of
tty_port_close if the port is console port.

Reproduce step:
- Run background processes from serial console
$ while true; do sleep 10; done &

- Log out
$ logout
-> Stuck

- Read journal log by journalctl | tail
Jan 28 16:07:01 ubuntu systemd[1]: Stopped Serial Getty on ttyAMA0.
Jan 28 16:07:01 ubuntu systemd[1]: Started Serial Getty on ttyAMA0.
Jan 28 16:07:02 ubuntu agetty[1643]: /dev/ttyAMA0: not a tty

Fixes: 761ed4a945 ("tty: serial_core: convert uart_close to use tty_port_close")
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Rob Herring <robh@kernel.org>
Cc: Jiri Slaby <jslaby@suse.com>
Signed-off-by: Chanho Park <parkch98@gmail.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-11-27 09:58:11 +01:00
Tobin C. Harding
863299001b tty_port: Remove incorrect whitespace after comments
Currently there are a bunch of kernel-doc function comments that have a
line of whitespace after the comment and before the function they
comment - this is incorrect, there should be no whitespace here.

Remove incorrect whitespace between comment and associated function.

Signed-off-by: Tobin C. Harding <me@tobin.cc>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-09-18 16:07:25 +02:00
Greg Kroah-Hartman
e3b3d0f549 tty: add SPDX identifiers to all remaining files in drivers/tty/
It's good to have SPDX identifiers in all files to make it easier to
audit the kernel tree for correct licenses.

Update the drivers/tty files files with the correct SPDX license
identifier based on the license text in the file itself.  The SPDX
identifier is a legally binding shorthand, which can be used instead of
the full boiler plate text.

This work is based on a script and data from Thomas Gleixner, Philippe
Ombredanne, and Kate Stewart.

Cc: Jiri Slaby <jslaby@suse.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Chris Metcalf <cmetcalf@mellanox.com>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: David Sterba <dsterba@suse.com>
Cc: James Hogan <jhogan@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Eric Anholt <eric@anholt.net>
Cc: Stefan Wahren <stefan.wahren@i2se.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Ray Jui <rjui@broadcom.com>
Cc: Scott Branden <sbranden@broadcom.com>
Cc: bcm-kernel-feedback-list@broadcom.com
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
Cc: Helge Deller <deller@gmx.de>
Cc: Joachim Eastwood <manabian@gmail.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Tobias Klauser <tklauser@distanz.ch>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Richard Genoud <richard.genoud@gmail.com>
Cc: Alexander Shiyan <shc_work@mail.ru>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: "Maciej W. Rozycki" <macro@linux-mips.org>
Cc: "Uwe Kleine-König" <kernel@pengutronix.de>
Cc: Pat Gefre <pfg@sgi.com>
Cc: "Guilherme G. Piccoli" <gpiccoli@linux.vnet.ibm.com>
Cc: Jason Wessel <jason.wessel@windriver.com>
Cc: Vladimir Zapolskiy <vz@mleia.com>
Cc: Sylvain Lemieux <slemieux.tyco@gmail.com>
Cc: Carlo Caione <carlo@caione.org>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Andy Gross <andy.gross@linaro.org>
Cc: David Brown <david.brown@linaro.org>
Cc: "Andreas Färber" <afaerber@suse.de>
Cc: Kevin Cernekee <cernekee@gmail.com>
Cc: Laxman Dewangan <ldewangan@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Peter Korsgaard <jacmet@sunsite.dk>
Cc: Timur Tabi <timur@tabi.org>
Cc: Tony Prisk <linux@prisktech.co.nz>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: "Sören Brinkmann" <soren.brinkmann@xilinx.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Kate Stewart <kstewart@linuxfoundation.org>
Cc: Philippe Ombredanne <pombredanne@nexb.com>
Cc: Jiri Slaby <jslaby@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-08 13:08:12 +01:00
Antonio Borneo
1926e5d37b ttyport: trivial fix for some typo in comments
Fix some minor typo spotted in comments:
- s/wit ha/with a/
- s/doestroyed/destroyed/

Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-09-18 18:31:48 +02:00
Greg Kroah-Hartman
fc098af16b Revert "tty: fix port buffer locking"
This reverts commit 925bb1ce47.

It causes lots of warnings and problems so for now, let's just revert
it.

Reported-by: <valdis.kletnieks@vt.edu>
Reported-by: Russell King <linux@armlinux.org.uk>
Reported-by: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Reported-by: Jiri Slaby <jslaby@suse.cz>
Reported-by: Andrey Konovalov <andreyknvl@google.com>
Acked-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-04 10:23:25 +02:00
Johan Hovold
8cde11b2ba tty/serdev: add serdev registration interface
Add a new interface for registering a serdev controller and clients, and
a helper function to deregister serdev devices (or a tty device) that
were previously registered using the new interface.

Once every driver currently using the tty_port_register_device() helpers
have been vetted and converted to use the new serdev registration
interface (at least for deregistration), we can move serdev registration
to the current helpers and get rid of the serdev-specific functions.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-05-18 17:38:24 +02:00
Vegard Nossum
925bb1ce47 tty: fix port buffer locking
tty_insert_flip_string_fixed_flag() is racy against itself when called
from the ioctl(TCXONC, TCION/TCIOFF) path [1] and the flush_to_ldisc()
workqueue path [2].

The problem is that port->buf.tail->used is modified without consistent
locking; the ioctl path takes tty->atomic_write_lock, whereas the workqueue
path takes ldata->output_lock.

We cannot simply take ldata->output_lock, since that is specific to the
N_TTY line discipline.

It might seem natural to try to take port->buf.lock inside
tty_insert_flip_string_fixed_flag() and friends (where port->buf is
actually used/modified), but this creates problems for flush_to_ldisc()
which takes it before grabbing tty->ldisc_sem, o_tty->termios_rwsem,
and ldata->output_lock.

Therefore, the simplest solution for now seems to be to take
tty->atomic_write_lock inside tty_port_default_receive_buf(). This lock
is also used in the write path [3] with a consistent ordering.

[1]: Call Trace:
 tty_insert_flip_string_fixed_flag
 pty_write
 tty_send_xchar                     // down_read(&o_tty->termios_rwsem)
                                    // mutex_lock(&tty->atomic_write_lock)
 n_tty_ioctl_helper
 n_tty_ioctl
 tty_ioctl                          // down_read(&tty->ldisc_sem)
 do_vfs_ioctl
 SyS_ioctl

[2]: Workqueue: events_unbound flush_to_ldisc
Call Trace:
 tty_insert_flip_string_fixed_flag
 pty_write
 tty_put_char
 __process_echoes
 commit_echoes                      // mutex_lock(&ldata->output_lock)
 n_tty_receive_buf_common
 n_tty_receive_buf2
 tty_ldisc_receive_buf              // down_read(&o_tty->termios_rwsem)
 tty_port_default_receive_buf       // down_read(&tty->ldisc_sem)
 flush_to_ldisc                     // mutex_lock(&port->buf.lock)
 process_one_work

[3]: Call Trace:
 tty_insert_flip_string_fixed_flag
 pty_write
 n_tty_write                        // mutex_lock(&ldata->output_lock)
                                    // down_read(&tty->termios_rwsem)
 do_tty_write (inline)              // mutex_lock(&tty->atomic_write_lock)
 tty_write                          // down_read(&tty->ldisc_sem)
 __vfs_write
 vfs_write
 SyS_write

The bug can result in about a dozen different crashes depending on what
exactly gets corrupted when port->buf.tail->used points outside the
buffer.

The patch passes my LOCKDEP/PROVE_LOCKING testing but more testing is
always welcome.

Found using syzkaller.

Cc: <stable@vger.kernel.org>
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-05-18 16:43:55 +02:00
Johan Hovold
d3ba126a22 Revert "tty_port: register tty ports with serdev bus"
This reverts commit 8ee3fde047.

The new serdev bus hooked into the tty layer in
tty_port_register_device() by registering a serdev controller instead of
a tty device whenever a serdev client is present, and by deregistering
the controller in the tty-port destructor. This is broken in several
ways:

Firstly, it leads to a NULL-pointer dereference whenever a tty driver
later deregisters its devices as no corresponding character device will
exist.

Secondly, far from every tty driver uses tty-port refcounting (e.g.
serial core) so the serdev devices might never be deregistered or
deallocated.

Thirdly, deregistering at tty-port destruction is too late as the
underlying device and structures may be long gone by then. A port is not
released before an open tty device is closed, something which a
registered serdev client can prevent from ever happening. A driver
callback while the device is gone typically also leads to crashes.

Many tty drivers even keep their ports around until the driver is
unloaded (e.g. serial core), something which even if a late callback
never happens, leads to leaks if a device is unbound from its driver and
is later rebound.

The right solution here is to add a new tty_port_unregister_device()
helper and to never call tty_device_unregister() whenever the port has
been claimed by serdev, but since this requires modifying just about
every tty driver (and multiple subsystems) it will need to be done
incrementally.

Reverting the offending patch is the first step in fixing the broken
lifetime assumptions. A follow-up patch will add a new pair of
tty-device registration helpers, which a vetted tty driver can use to
support serdev (initially serial core). When every tty driver uses the
serdev helpers (at least for deregistration), we can add serdev
registration to tty_port_register_device() again.

Note that this also fixes another issue with serdev, which currently
allocates and registers a serdev controller for every tty device
registered using tty_port_device_register() only to immediately
deregister and deallocate it when the corresponding OF node or serdev
child node is missing. This should be addressed before enabling serdev
for hot-pluggable buses.

Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-05-18 16:41:49 +02:00
Ingo Molnar
174cd4b1e5 sched/headers: Prepare to move signal wakeup & sigpending methods from <linux/sched.h> into <linux/sched/signal.h>
Fix up affected files that include this signal functionality via sched.h.

Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2017-03-02 08:42:32 +01:00
Rob Herring
8ee3fde047 tty_port: register tty ports with serdev bus
Register a serdev controller with the serdev bus when a tty_port is
registered. This creates the serdev controller and create's serdev
devices for any DT child nodes of the tty_port's parent (i.e. the UART
device).

Signed-off-by: Rob Herring <robh@kernel.org>
Reviewed-By: Sebastian Reichel <sre@kernel.org>
Tested-By: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-02-03 10:17:02 +01:00
Rob Herring
c3485ee0d5 tty_port: Add port client functions
Introduce a client (upward direction) operations struct for tty_port
clients. Initially supported operations are for receiving data and write
wake-up. This will allow for having clients other than an ldisc.

Convert the calls to the ldisc to use the client ops as the default
operations.

Signed-off-by: Rob Herring <robh@kernel.org>
Reviewed-By: Sebastian Reichel <sre@kernel.org>
Tested-By: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-02-03 10:17:02 +01:00
Rob Herring
3086365db6 tty_port: make tty_port_register_device wrap tty_port_register_device_attr
tty_register_device is just a wrapper for tty_register_device_attr with
NULL passed for drvdata and attr_grp. So similarly make
tty_port_register_device a wrapper of tty_port_register_device_attr so that
additions don't have to be made in both functions.

Signed-off-by: Rob Herring <robh@kernel.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-By: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-01-19 17:22:34 +01:00
Alan Cox
ed3f0af8c0 tty_port: allow a port to be opened with a tty that has no file handle
Let us create tty objects entirely in kernel space. Untested proposal to
show why all the ideas around rewriting half the uart stack are not needed.

With this a kernel created non file backed tty object could be used to handle
data, and set terminal modes. Not all ldiscs can cope with this as N_TTY in
particular has to work back to the fs/tty layer.

The tty_port code is however otherwise clean of file handles as far as I can
tell as is the low level tty port write path used by the ldisc, the
configuration low level interfaces and most of the ldiscs.

Currently you don't have any exposure to see tty hangups because those are
built around the file layer. However a) it's a fixed port so you probably
don't care about that b) if you do we can add a callback and c) you almost
certainly don't want the userspace tear down/rebuild behaviour anyway.

This should however be sufficient if we wanted for example to enumerate all
the bluetooth bound fixed ports via ACPI and make them directly available.
It doesn't deal with the case of a user opening a port that's also kernel
opened and that would need some locking out (so it returned EBUSY if bound
to a kernel device of some kind). That needs resolving along with how you
"up" or "down" your new bluetooth device, or enumerate it while providing
the existing tty API to avoid regressions (and to debug).

Signed-off-by: Alan Cox <alan@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-By: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-01-19 17:22:34 +01:00
Peter Hurley
d41861ca19 tty: Replace ASYNC_INITIALIZED bit and update atomically
Replace ASYNC_INITIALIZED bit in the tty_port::flags field with
TTY_PORT_INITIALIZED bit in the tty_port::iflags field. Introduce helpers
tty_port_set_initialized() and tty_port_initialized() to abstract
atomic bit ops.

Note: the transforms for test_and_set_bit() and test_and_clear_bit()
are unnecessary as the state transitions are already mutually exclusive;
the tty lock prevents concurrent open/close/hangup.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-04-30 09:26:55 -07:00
Peter Hurley
807c8d81f4 tty: Replace ASYNC_NORMAL_ACTIVE bit and update atomically
Replace ASYNC_NORMAL_ACTIVE bit in the tty_port::flags field with
TTY_PORT_ACTIVE bit in the tty_port::iflags field. Introduce helpers
tty_port_set_active() and tty_port_active() to abstract atomic bit ops.

Extract state changes from port lock sections, as this usage is
broken and confused; the state transitions are protected by the
tty lock (which mutually excludes parallel open/close/hangup),
and no user tests the active state while holding the port lock.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-04-30 09:26:55 -07:00
Peter Hurley
18900ca65a tty: Replace TTY_IO_ERROR bit tests with tty_io_error()
Abstract TTY_IO_ERROR status test treewide with tty_io_error().
NB: tty->flags uses atomic bit ops; replace non-atomic bit test
with test_bit().

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-04-30 09:26:55 -07:00
Peter Hurley
afc5ab0965 tty: Remove ASYNC_CLOSING
The tty core no longer provides nor uses ASYNC_CLOSING; remove from
tty_port_close_start() and tty_port_close_end() as well as tty drivers
which open-code these state changes. Unfortunately, even though the
bit is masked from userspace, its inclusion in a uapi header precludes
removing the macro.

Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux-s390@vger.kernel.org
Cc: Mikael Starvik <starvik@axis.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: linux-cris-kernel@axis.com
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-01-28 14:19:12 -08:00
Peter Hurley
9db276f8f0 tty: Use termios c_*flag macros
Expressions of the form "tty->termios.c_*flag & FLAG"
are more clearly expressed with the termios flags macros,
I_FLAG(), C_FLAG(), O_FLAG(), and L_FLAG().

Convert treewide.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Acked-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-01-28 14:13:44 -08:00
Peter Hurley
5823323ea5 tty: Allow unreadable mess to be > 80 chars
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-01-28 14:13:44 -08:00
Peter Hurley
339f36ba14 tty: Define tty_*() printk macros
Since not all ttys are devices (eg., SysV ptys), dev_*() printk macros
cannot be used. Define tty_*() printk macros that output in similar
format to dev_*() macros (ie., <driver> <tty>: .....).

Transform the most-trivial printk( LEVEL ...) usage to tty_*() usage.
NB: The function name has been eliminated from messages with unique
context, or prefixed to the format when given.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-13 19:59:48 -08:00
Peter Hurley
e176058f0d tty: Abstract tty buffer work
Introduce API functions to restart and cancel tty buffer work, rather
than manipulate buffer work directly.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-17 21:32:21 -07:00
Peter Hurley
cc2aaabfd6 tty: Remove tty_port::close_wait
With the removal of tty_wait_until_sent_from_close(), tty drivers
no longer wait during open for parallel closes to complete (instead,
the tty core waits before calling the driver open() method). Thus,
the close_wait waitqueue is no longer used for waiting.

Remove struct tty_port::close_wait.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-17 21:11:29 -07:00
Peter Hurley
fef062cbf2 tty: Remove ASYNC_CLOSING checks in open()/hangup() methods
Since at least before 2.6.30, tty drivers that do not drop the tty lock
while closing cannot observe ASYNC_CLOSING set while holding the
tty lock; this includes the tty driver's open() and hangup() methods,
since the tty core calls these methods holding the tty lock.

For these drivers, waiting for ASYNC_CLOSING to clear while opening
is not required, since this condition cannot occur. Similarly, even
when the open() method drops and reacquires the tty lock after
blocking, ASYNC_CLOSING cannot be set (again, for drivers that
do not drop the tty lock while closing).

Now that tty port drivers no longer drop the tty lock while closing
(since 'tty: Remove tty_wait_until_sent_from_close()'), the same
conditions apply: waiting for ASYNC_CLOSING to clear while opening
is not required, nor is re-checking ASYNC_CLOSING after dropping and
reacquiring the tty lock while blocking (eg., in *_block_til_ready()).

Note: The ASYNC_CLOSING flag state is still maintained since several
bitrotting drivers use it for (dubious) other purposes.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-17 21:11:29 -07:00
Peter Hurley
79c1faa451 tty: Remove tty_wait_until_sent_from_close()
tty_wait_until_sent_from_close() drops the tty lock while waiting
for the tty driver to finish sending previously accepted data (ie.,
data remaining in its write buffer and transmit fifo).

tty_wait_until_sent_from_close() was added by commit a57a7bf3fc
("TTY: define tty_wait_until_sent_from_close") to prevent the entire
tty subsystem from being unable to open new ttys while waiting for
one tty to close while output drained.

However, since commit 0911261d4c ("tty: Don't take tty_mutex for tty
count changes"), holding a tty lock while closing does not prevent other
ttys from being opened/closed/hung up, but only prevents lifetime event
changes for the tty under lock.

Holding the tty lock while waiting for output to drain does prevent
parallel non-blocking opens (O_NONBLOCK) from advancing or returning
while the tty lock is held. However, all parallel opens _already_
block even if the tty lock is dropped while closing and the parallel
open advances. Blocking in open has been in mainline since at least 2.6.29
(see tty_port_block_til_ready(); note the test for O_NONBLOCK is _after_
the wait while ASYNC_CLOSING).

IOW, before this patch a non-blocking open will sleep anyway for the
_entire_ duration of a parallel hardware shutdown, and when it wakes, the
error return will cause a release of its tty, and it will restart with
a fresh attempt to open. Similarly with a blocking open that is already
waiting; when it's woken, the hardware shutdown has already completed
to ASYNC_INITIALIZED is not set, which forces a release and restart as
well.

So, holding the tty lock across the _entire_ close (which is what this
patch does), even while waiting for output to drain, is equivalent to
the current outcome wrt parallel opens.

Cc: Alan Cox <alan@linux.intel.com>
Cc: David Laight <David.Laight@aculab.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Karsten Keil <isdn@linux-pingi.de>
CC: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-17 21:11:29 -07:00
Markus Elfring
a211b1af19 tty: Deletion of unnecessary checks before two function calls
The functions put_device() and tty_kref_put() test whether their argument
is NULL and then return immediately.
Thus the test around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-26 19:35:49 -08:00
Peter Hurley
3f40f5b2a2 tty: Flush tty buffers after hardware shutdown
The line discipline buffer and the tty buffers must be flushed again
after hardware shutdown; otherwise, a brief window exists between the
ldisc flush in tty_port_close_start() and the subsequent
tty_port_shutdown(), during which more data could be received into the
tty buffers. A racing open might then be able to receive data from the
previous session.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-06 14:57:27 -08:00
Peter Hurley
633caba893 tty: Move tty hung up check from port->lock critical section
The port->lock does not protect the filp->f_op field; move
the tty_hung_up_p() test outside the port->lock critical section
in tty_port_close_start().

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-06 14:57:27 -08:00
Peter Hurley
e359a4e38d tty: Remove tty_hung_up_p() tests from tty drivers' open()
Since at least before 2.6.30, it has not been possible to observe
a hung up file pointer in a tty driver's open() method unless/until
the driver open() releases the tty_lock() (eg., before blocking).

This is because tty_open() adds the file pointer while holding
the tty_lock() _and_ doesn't release the lock until after calling
the tty driver's open() method. [ Before tty_lock(), this was
lock_kernel(). ]

Since __tty_hangup() first waits on the tty_lock() before
enumerating and hanging up the open file pointers, either
__tty_hangup() will wait for the tty_lock() or tty_open() will
not yet have added the file pointer. For example,

CPU 0                          |  CPU 1
                               |
tty_open                       |  __tty_hangup
  ..                           |    ..
  tty_lock                     |    ..
  tty_reopen                   |    tty_lock  / blocks
  ..                           |
  tty_add_file(tty, filp)      |
  ..                           |
  tty->ops->open(tty, filp)    |
    tty_port_open              |
      tty_port_block_til_ready |
        ..                     |
        while (1)              |
          ..                   |
          tty_unlock           |    / unblocks
          schedule             |    for each filp on tty->tty_files
                               |      f_ops = tty_hung_up_fops;
                               |    ..
                               |    tty_unlock
          tty_lock             |
  ..                           |
  tty_unlock                   |

Note that since tty_port_block_til_ready() and similar drop
the tty_lock while blocking, when woken, the file pointer
must then be tested for having been hung up.

Also, fix bit-rotted drivers that used extra_count to track the
port->count bump.

CC: Mikael Starvik <starvik@axis.com>
CC: Samuel Ortiz <samuel@sortiz.org>
CC: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-07-10 16:06:49 -07:00
Peter Hurley
ddc7b758a6 tty: Move tty->closing from port lock critical section
tty->closing informs the line discipline that the hardware will
be shutting down imminently, and to disable further input other
than soft flow control (but to still allow additional output).

However, the tty lock is the necessary lock for preventing
concurrent changes to tty->closing. As shown by the call-tree
audit [1] of functions that modify tty->closing, the tty lock
is already held for those functions.

[1]
Call-tree audit of functions that modify tty->closing
* does not include call tree to tty_port_close(), tty_port_close_start(),
  or tty_port_close_end() which is already documented in
  'tty: Document locking for tty_port_close{,start,end}' that shows
  callers to those 3 functions hold the tty lock

tty_release()
  tty->ops->close() --+
                      |
__tty_hangup()        |
  tty->ops->close() --+
                      |
        mp_close():drivers/staging/sb105x/sb_pci_mp.c
        dngc_tty_close():drivers/staging/dgnc/dgnc_tty.c
        dgap_tty_close():drivers/staging/dgap/dgap_tty.c
        dgrp_tty_close():drivers/staging/dgrp/dgrp_tty.c
        rp_close():drivers/tty/rocket.c
        hvsi_close():drivers/tty/hvc/hvsi.c
        rs_close():drivers/tty/serial/68328serial.c
        rs_close():drivers/tty/serial/crisv10.c
        uart_close():drivers/tty/serial/serial_core.c
        isdn_tty_close():drivers/isdn/i4l/isdn_tty.c
        tty3215_close():drivers/s390/char/con3215.c

tty_open()
  tty_ldisc_setup() ----+
                        |
__tty_hangup()          |
  tty_ldisc_hangup() ---+
                        |
tty_set_ldisc() --------+
  tty_ldisc_restore() --+
                        |
                        +- tty_ldisc_open()
                             ld->ops->open() --+
                                               |
                                               +- n_tty_open()

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-07-10 16:06:48 -07:00
Peter Hurley
9c9928bded tty: Document locking for tty_port_hangup()
The tty lock is held when the tty driver's hangup() method is called
(from the lone call-site, __tty_hangup()). The call-tree audit [1]
of tty_port_hangup() is a closed graph of the callers of
tty_port_hangup(); ie., all callers originate only from __tty_hangup().

Of these callers, none drop the tty lock prior to calling
tty_port_hangup().

[1]
Call-tree audit of tty_port_hangup()

__tty_hangup()
  tty->ops->hangup() --+
                       |
        rs_hangup():arch/ia64/hp/sim/simserial.c
        line_hangup():arch/um/drivers/line.c
        gdm_tty_hangup():drivers/staging/gdm724x/gdm_tty.c
        fwtty_hangup():drivers/staging/fwserial/fwserial.c
        acm_tty_hangup():drivers/usb/class/cdc-acm.c
        serial_hangup():drivers/usb/serial/usb-serial.c
        ipoctal_hangup():drivers/ipack/devices/ipoctal.c
        cy_hangup():drivers/tty/cyclades.c
        isicom_hangup():drivers/tty/isicom.c
        rp_hangup():drivers/tty/rocket.c
        dashtty_hangup():drivers/tty/metag_da.c
        moxa_hangup():drivers/tty/moxa.c
        gsmtty_hangup():drivers/tty/n_gsm.c
        goldfish_tty_hangup():drivers/tty/goldfish.c
        ehv_bc_tty_hangup():drivers/tty/ehv_bytechan.c
        mxser_hangup():drivers/tty/mxser.c
        kgdb_nmi_tty_hangup():drivers/tty/serial/kgdb_nmi.c
        ifx_spi_hangup():drivers/tty/serial/ifx6x60.c
        ntty_hangup():drivers/tty/nozomi.c
        capinc_tty_hangup():drivers/isdn/capi/capi.c
        mgslpc_hangup():drivers/char/pcmcia/synclink_cs.c
        sdio_uart_hangup():drivers/mmc/card/sdio_uart.c
        rfcomm_tty_hangup():net/bluetooth/rfcomm/tty.c
                       |
                       +- tty_port_hangup()

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-07-10 16:05:19 -07:00
Peter Hurley
c590f6b6cf tty: Document locking for tty_port_block_til_ready()
The tty lock is held when the tty driver's open() method is called
(from tty_open()). The call-tree audit [1] of tty_port_block_til_ready()
is a closed graph of the callers of tty_port_block_til_ready();
ie., all callers originate only from tty_open().

Of these callers, none drop the tty lock.

Also, document tty_port_block_til_ready() may drop and reacquire
the tty lock when blocking, which means the tty or tty_port may have
changed state.

[1]
Call-tree audit of tty_port_block_til_ready()
* does not include call tree of tty_port_open() which is already
  documented in 'tty: Document locking from tty_port_open()'

tty_open()
  tty->ops->open() --+
                     |
        cy_open():drivers/tty/cyclades.c
        rp_open():drivers/tty/rocket.c
        rs_open():drivers/tty/amiserial.c
        moxa_open():drivers/tty/moxa.c
        gsmtty_open():drivers/tty/n_gsm.c
        rs_open():drivers/tty/serial/68328serial.c
        uart_open():drivers/tty/serial/serial_core.c
        isdn_tty_open():drivers/isdn/i4l/isdn_tty.c
        mgslpc_open():drivers/char/pcmcia/synclink_cs.c
                     |
                     +- tty_port_block_til_ready()

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-07-10 16:05:19 -07:00
Peter Hurley
addd4672bb tty: Document locking for tty_port_open()
The tty lock is held when the tty driver's open method is called
(from the lone call-site, tty_open()). The call-tree audit [1] of
tty_port_open() is a closed graph of the callers of tty_port_open();
ie., all callers originate from only tty_open().

Of these callers, none drop the tty lock.

Also, document that tty_port_block_til_ready() may drop and reacquire
the tty lock when blocking, which means the tty or tty_port may have
changed state.

[1]
Call-tree audit of tty_port_open()

tty_open()
  tty->ops->open() --+
                     |
        rs_open():arch/ia64/hp/sim/simserial.c
       *line_open():arch/um/drivers/line.c
        gdm_tty_open():drivers/staging/gdm724x/gdm_tty.c
        fwtty_open():drivers/staging/fwserial/fwserial.c
        acm_tty_open():drivers/usb/class/cdc-acm.c
        serial_open():drivers/usb/serial/usb-serial.c
        pti_tty_driver_open():drivers/misc/pti.c
        ipoctal_open():drivers/ipack/devices/ipoctal.c
        isicom_open():drivers/tty/isicom.c
        dashtty_open():drivers/tty/metag_da.c
        goldfish_tty_open():drivers/tty/goldfish.c
        ehv_bc_tty_open():drivers/tty/ehv_bytechan.c
        mxser_open():drivers/tty/mxser.c
        kgdb_nmi_tty_open():drivers/tty/serial/kgdb_nmi.c
        ifx_spi_open():drivers/tty/serial/ifx6x60.c
        smd_tty_open():drivers/tty/serial/msm_smd_tty.c
        ntty_open():drivers/tty/nozomi.c
        capinc_tty_open():drivers/isdn/capi/capi.c
        tpk_open():drivers/char/ttyprintk.c
        sdio_uart_open():drivers/mmc/card/sdio_uart.c
        rfcomm_tty_open():net/bluetooth/rfcomm/tty.c
                     |
                     +- tty_port_open()

* line_open() is the .open method for 2 um drivers
  declared in ./arch/um/drivers/stdio_console.c and
  in ./arch/um/drivers/ssl.c, and not called directly

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-07-10 16:05:19 -07:00
Peter Hurley
0733db91d0 tty: Document locking for tty_port_close{,start,end}()
The tty lock is held when the tty driver's .close method is called
(from the two lone call-sites of tty_release() and __tty_hangup()).
The call-tree audit[1] of tty_port_close(), tty_port_close_start,
and tty_port_close_end() is a closed graph of the callers of these
3 functions; ie., all callers originate from only tty_release()
or __tty_hangup().

Of these callers, none drop the tty lock.

Also, document tty_port_close_start() may drop and reacquire the
tty lock in tty_wait_until_sent_from_close(), which means the tty
or tty_port may have changed state (but not reopened or hung up).

[1]
Call-tree audit of tty_port_close, tty_port_close_start, and tty_port_close_end()

tty_release()
  tty->ops->close() --+
                      |
__tty_hangup()        |
  tty->ops->close() --+
                      |
                      +- rp_close():drivers/tty/rocket.c -------------------+
                      +- uart_close():drivers/tty/serial/serial_core.c -----+
                      |                                                     +- tty_port_close_start()
                      |
                      |
                      +- close():drivers/tty/synclinkmp.c ------------------+
                      +- rs_close():drivers/tty/amiserial.c ----------------+
                      +- gsmtty_close():drivers/tty/n_gsm.c ----------------+
                      +- mxser_close():drivers/tty/mxser.c -----------------+
                      +- close():drivers/tty/synclink_gt.c -----------------+
                      +- mgsl_close():drivers/tty/synclink.c ---------------+
                      +- isdn_tty_close():drivers/isdn/i4l/isdn_tty.c ------+
                      +- mgslpc_close():drivers/char/pcmcia/synclink_cs.c --+
                      +- ircomm_tty_close():net/irda/ircomm/ircomm_tty.c ---+
                      |                                                     |
        rs_close():arch/ia64/hp/sim/simserial.c                             |
       *line_close():arch/um/drivers/line.c                                 |
        gdm_tty_close():drivers/staging/gdm724x/gdm_tty.c
        fwtty_close():drivers/staging/fwserial/fwserial.c
        acm_tty_close():drivers/usb/class/cdc-acm.c
        serial_close():drivers/usb/serial/usb-serial.c
        pti_tty_driver_close():drivers/misc/pti.c
        ipoctal_close():drivers/ipack/devices/ipoctal.c
        cy_close():drivers/tty/cyclades.c
        isicom_close():drivers/tty/isicom.c
        dashtty_close():drivers/tty/metag_da.c
        moxa_close():drivers/tty/moxa.c
        goldfish_tty_close():drivers/tty/goldfish.c
        ehv_bc_tty_close():drivers/tty/ehv_bytechan.c
        kgdb_nmi_tty_close():drivers/tty/serial/kgdb_nmi.c
        ifx_spi_close():drivers/tty/serial/ifx6x60.c
        smd_tty_close():drivers/tty/serial/msm_smd_tty.c
        ntty_close():drivers/tty/nozomi.c
        capinc_tty_close():drivers/isdn/capi/capi.c
        tpk_close():drivers/char/ttyprintk.c
        sdio_uart_close():drivers/mmc/card/sdio_uart.c                      |
        rfcomm_tty_close():net/bluetooth/rfcomm/tty.c                       |
                      |                                                     |
                      +- tty_port_close():drivers/tty/tty_port.c -----------+
                                                                            |
                                                                            +- tty_port_close_start()
                                                                            +- tty_port_close_end()

* line_close() is the .close method for 2 um drivers,
  declared in ./arch/um/drivers/stdio_console.c and
  in ./arch/um/drivers/ssl.c, and not called directly

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-07-10 16:05:19 -07:00
Paul Gortmaker
f8e87cb4a1 tty: delete non-required instances of include <linux/init.h>
None of these files are actually using any __init type directives
and hence don't need to include <linux/init.h>.  Most are just a
left over from __devinit and __cpuinit removal, or simply due to
code getting copied from one driver to the next.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-01-07 17:05:21 -08:00
Peter Hurley
469d6d0631 tty: Remove unused drop() method from tty_port interface
Although originally conceived as a hook for port drivers to know
when a port reference is dropped, no driver uses this method.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-09-25 18:08:34 -07:00
Peter Hurley
e3bfea23a6 tty: Prevent tty_port destruction if tty not released
If the tty driver mistakenly drops the last port reference
before the tty has been released, issue a diagnostic and
abort the port destruction.

This will leak memory and may zombify the port, but might
otherwise keep the machine in runnable state.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-09-25 18:08:34 -07:00
Gianluca Anzolin
1d9e689c93 tty_port: Fix refcounting leak in tty_port_tty_hangup()
The function tty_port_tty_hangup() could leak a reference to the tty_struct:

        struct tty_struct *tty = tty_port_tty_get(port);

        if (tty && (!check_clocal || !C_CLOCAL(tty))) {
                tty_hangup(tty);
                tty_kref_put(tty);
        }

If tty != NULL and the second condition is false we never call tty_kref_put and
the reference is leaked.

Fix by always calling tty_kref_put() which accepts a NULL argument.

The patch fixes a regression introduced by commit aa27a094.

Acked-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Gianluca Anzolin <gianluca@sottospazio.it>
Acked-by: Jiri Slaby <jslaby@suse.cz>
Cc: stable <stable@vger.kernel.org> # 3.10
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-07-26 16:34:00 -07:00
Peter Hurley
4f98d46751 tty: Complete ownership transfer of flip buffers
Waiting for buffer work to complete is not required for safely
performing changes to the line discipline, once the line discipline
is halted. The buffer work routine, flush_to_ldisc(), will be
unable to acquire an ldisc ref and all existing references were
waited until released (so it can't already have one).

Ensure running buffer work which may reference the soon-to-be-gone
tty completes and any buffer work running after this point retrieves
a NULL tty.

Also, ensure all buffer work is cancelled on port destruction.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-03-18 16:44:02 -07:00
Johan Hovold
0b2588cadf TTY: fix close of uninitialised ports
Make sure we do not make tty-driver callbacks or wait for port to drain
on uninitialised ports (e.g. when open failed) in
tty_port_close_start().

No callback, such as flush_buffer or wait_until_sent, needs to be made
on a port that has never been opened. Neither does it make much sense to
add drain delay for an uninitialised port.

Currently a drain delay of up to two seconds could be added when a tty
fails to open.

Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-03-18 16:27:54 -07:00
Johan Hovold
b74414f5f3 TTY: clean up port drain-delay handling
Move port drain-delay handling to a separate function.

Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-03-18 16:27:54 -07:00
Johan Hovold
957dacaee5 TTY: fix DTR not being dropped on hang up
Move HUPCL handling to port shutdown so that DTR is dropped also on hang
up (tty_port_close is a noop for hung-up ports).

Also do not try to drop DTR for uninitialised ports where it has never
been raised (e.g. after a failed open).

Note that this is also the current behaviour of serial-core.

Nine drivers currently call tty_port_close_start directly (rather than
through tty_port_close) and seven of them lower DTR as part of their
close (if the port has been initialised). Fixup the remaining two
drivers so that it continues to be lowered also on normal (non-HUP)
close. [ Note that most of those other seven drivers did not expect DTR
to have been dropped by tty_port_close_start in the first place. ]

Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-03-18 16:27:53 -07:00
Johan Hovold
e584a02cf5 TTY: fix DTR being raised on hang up
Make sure to check ASYNC_INITIALISED before raising DTR when waking up
from blocked open in tty_port_block_til_ready.

Currently DTR could get raised at hang up as a blocked process would
raise DTR unconditionally before checking for hang up and returning.

Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-03-18 16:27:53 -07:00
Johan Hovold
31ca020b57 TTY: wake up processes last at hangup
Move wake up of processes on blocked-open and modem-status wait queues
to after port shutdown at hangup.

This way the woken up processes can use the ASYNC_INITIALIZED flag to
detect port shutdown.

Note that this is the order currently used by serial-core.

Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-03-18 16:27:53 -07:00
Johan Hovold
8bde9658a0 TTY: clean up port shutdown
Untangle port-shutdown logic and make sure the initialised flag is
always cleared for non-console ports.

Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-03-18 16:27:53 -07:00