diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2016-11-25 18:20:51 -0800 |
---|---|---|
committer | Oleksandr Suvorov <oleksandr.suvorov@toradex.com> | 2021-01-27 11:03:27 +0200 |
commit | 51ccbda553f88d6d4262726c3bcc240d833695c8 (patch) | |
tree | 6439eb2361f8b0652a5035d1bde9772768987bc3 /drivers/rpmsg | |
parent | b4afeb8e4f41948b83d0b32653b1ad56611e5cf9 (diff) |
rpmsg: imx: do not push data when no reader is available
Pushing data while there is no reader seems to lock/crash the TTY
layer in some way. Especially when a reader gets attached again,
the kernel crashes with
Unable to handle kernel paging request at virtual address 00002248
Also use tty_insert_flip_string which handels the copying and TTY
buffer resizing if necessary.
Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
Acked-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
(cherry picked from commit 5aba75e2c61d4044bed21730b7c471822860fac1)
(cherry picked from commit db0da7d68e090eb2150b267df2d9d9b4d9edf52f)
Changed to non void function: add required return value.
Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com>
Diffstat (limited to 'drivers/rpmsg')
-rw-r--r-- | drivers/rpmsg/imx_rpmsg_tty.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/drivers/rpmsg/imx_rpmsg_tty.c b/drivers/rpmsg/imx_rpmsg_tty.c index 008c998b610e..eaeff739a2b9 100644 --- a/drivers/rpmsg/imx_rpmsg_tty.c +++ b/drivers/rpmsg/imx_rpmsg_tty.c @@ -30,9 +30,16 @@ struct rpmsgtty_port { static int rpmsg_tty_cb(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 src) { - int space; - unsigned char *cbuf; + int copied; struct rpmsgtty_port *cport = dev_get_drvdata(&rpdev->dev); + struct tty_struct *tty = dev_get_drvdata(&rpdev->dev); + + /* no one left to give data to, so sleep */ + if (tty == NULL) { + dev_dbg(&rpdev->dev, "waiting for readers, discard len %d\n", + len); + return 0; + } /* flush the recv-ed none-zero data to tty node */ if (len == 0) @@ -40,18 +47,14 @@ static int rpmsg_tty_cb(struct rpmsg_device *rpdev, void *data, int len, dev_dbg(&rpdev->dev, "msg(<- src 0x%x) len %d\n", src, len); - print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1, - data, len, true); + print_hex_dump_debug(__func__, DUMP_PREFIX_NONE, 16, 1, + data, len, true); spin_lock_bh(&cport->rx_lock); - space = tty_prepare_flip_string(&cport->port, &cbuf, len); - if (space <= 0) { - dev_err(&rpdev->dev, "No memory for tty_prepare_flip_string\n"); - spin_unlock_bh(&cport->rx_lock); - return -ENOMEM; - } + copied = tty_insert_flip_string(&cport->port, data, len); + if (copied != len) + dev_err_ratelimited(&rpdev->dev, "RX copy to tty layer failed\n"); - memcpy(cbuf, data, len); tty_flip_buffer_push(&cport->port); spin_unlock_bh(&cport->rx_lock); |