aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2019-01-28 07:02:49 -0800
committerPavel <pavel@ucw.cz>2019-01-29 11:26:11 +0100
commit8ccf8f2525e20ba7a9d6617933d5b0da2dc6c620 (patch)
tree0b3dd76c4ee34cfc1bd87b6c52721f2291919fbd
parent68043c3bfa65978ca79805b68a34ef854f2edce6 (diff)
downloadlinux-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.c68
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: