summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2016-11-25 18:20:51 -0800
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2017-01-10 23:13:33 +0100
commit5aba75e2c61d4044bed21730b7c471822860fac1 (patch)
tree86f3658a4f925408585980736f07b13433589b0a
parentcade8f64c93ad5086b755a24ba81046c77bfa31b (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>
-rw-r--r--drivers/rpmsg/imx_rpmsg_tty.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/rpmsg/imx_rpmsg_tty.c b/drivers/rpmsg/imx_rpmsg_tty.c
index 14904c7d517e..47c0dd17fa61 100644
--- a/drivers/rpmsg/imx_rpmsg_tty.c
+++ b/drivers/rpmsg/imx_rpmsg_tty.c
@@ -39,9 +39,16 @@ static struct rpmsgtty_port rpmsg_tty_port;
static void rpmsg_tty_cb(struct rpmsg_channel *rpdev, void *data, int len,
void *priv, u32 src)
{
- int space;
- unsigned char *cbuf;
+ int copied;
struct rpmsgtty_port *cport = &rpmsg_tty_port;
+ struct tty_struct *tty = tty_port_tty_get(&cport->port);
+
+ /* 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;
+ }
/* flush the recv-ed none-zero data to tty node */
if (len == 0)
@@ -49,18 +56,15 @@ static void rpmsg_tty_cb(struct rpmsg_channel *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;
+ 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);
}