diff options
author | Tony Lindgren <tony@atomide.com> | 2019-01-28 07:02:49 -0800 |
---|---|---|
committer | Pavel <pavel@ucw.cz> | 2019-01-29 11:26:11 +0100 |
commit | 8ccf8f2525e20ba7a9d6617933d5b0da2dc6c620 (patch) | |
tree | 0b3dd76c4ee34cfc1bd87b6c52721f2291919fbd | |
parent | 68043c3bfa65978ca79805b68a34ef854f2edce6 (diff) | |
download | linux-k-8ccf8f2525e20ba7a9d6617933d5b0da2dc6c620.tar.gz |
mfd: motmdm: Fix voice call regression with reversed line breakm-v5.0-rc1-10
Commit 11ee629ad7ae ("mfd: motmdm: Fix reversed line break")
broke voice calls it seems. Turns out we should only tinker with
the packets for the kfifo for the character devices to keep apps
like minicom happy. With the line break fix we were incorrectly
also fixing up the packets for device drivers that is not
necessary.
Let's fix this by adding a separate function for feeding kfifo.
Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r-- | drivers/mfd/motorola-mdm.c | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/drivers/mfd/motorola-mdm.c b/drivers/mfd/motorola-mdm.c index 9fd65d1fcc8eea..0a8d15565f9ba0 100644 --- a/drivers/mfd/motorola-mdm.c +++ b/drivers/mfd/motorola-mdm.c @@ -248,6 +248,36 @@ static void motmdm_read_state(struct motmdm_dlci *mot_dlci, } } +/* Fix line breaks for apps if needed and feed kfifo */ +static int motmdm_dlci_feed_kfifo(struct motmdm_dlci *mot_dlci, + const unsigned char *buf, + size_t len) +{ + int err, trim = 0; + size_t newlen = len; + + if (len && buf[len - 1] == '\n') { + if (len > 1 && buf[len - 2] != '\r') + newlen--; + else if (len == 1) + newlen--; + } + + err = kfifo_in(&mot_dlci->read_fifo, buf, newlen); + if (err != newlen) + return -ENOSPC; + + if (newlen != len) { + err = kfifo_in(&mot_dlci->read_fifo, "\r\n", 2); + if (err != 2) + err = -ENOSPC; + else + newlen += err; + } + + return newlen; +} + /* * Read handling for Motorola custom layering on top of TS 27.010 */ @@ -262,7 +292,6 @@ static int motmdm_dlci_receive_buf(struct gsm_serdev_dlci *gsm_dlci, const unsigned char *msg; size_t msglen; int id, err; - bool terminate = false; if (len < (MOTMDM_ID_LEN + 1) || buf[0] != 'U') return 0; @@ -275,44 +304,23 @@ static int motmdm_dlci_receive_buf(struct gsm_serdev_dlci *gsm_dlci, msg = buf + MOTMDM_ID_LEN; msglen = len - MOTMDM_ID_LEN; - /* Need a fixup for '\r\n' terminated lines? */ - if (msglen && msg[msglen - 1] == '\n') { - if (msglen > 1 && msg[msglen - 2] != '\r') { - terminate = true; - msglen--; - } else if (msglen == 1) { - terminate = true; - msglen--; - } - } - if (mot_dlci->line == ddata->cfg->modem_dlci) motmdm_read_state(mot_dlci, msg, msglen); - if (kfifo_initialized(&mot_dlci->read_fifo)) { - err = kfifo_in(&mot_dlci->read_fifo, msg, msglen); - if (err != msglen) { - err = -ENOSPC; - goto err_kfifo; - } - - if (terminate) { - err = kfifo_in(&mot_dlci->read_fifo, "\r\n", 2); - if (err != 2) - err = -ENOSPC; - else - msglen += err; - } - } - - err = msglen; - /* Motorola custom data or a command ack? */ if (buf[MOTMDM_ID_LEN] == '~' && mot_dlci->receive_data) mot_dlci->receive_data(mot_dlci, msg + 1, msglen - 1); else if (mot_dlci->handle_command) mot_dlci->handle_command(mot_dlci, id, msg, msglen); + if (kfifo_initialized(&mot_dlci->read_fifo)) { + err = motmdm_dlci_feed_kfifo(mot_dlci, msg, msglen); + if (err < 0) + goto err_kfifo; + } + + err = msglen; + wake_up_interruptible(&mot_dlci->read_queue); err_kfifo: |