msm: tty: update receive room just before writing data to the ldisc
There is a corner case in the tty driver where the value of
tty->receive_room is not being updated before writing data to
the line discipline. When this happens, data is lost because
of failure to re-submit any remaining data to the ldisc.
This fix is dependent on a new tty flag that is set only when
the tty driver is used for efs sync betweem the mdm modem and
the applications processor.
CRs-Fixed: 358868
Change-Id: I0ba02980504b4d8187b8c83111c2c883d194efa2
Signed-off-by: Joel King <joelking@codeaurora.org>
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 6c9b7cd..ccbaa6d 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -418,6 +418,8 @@
int count;
char *char_buf;
unsigned char *flag_buf;
+ unsigned int left = 0;
+ unsigned int max_space;
count = head->commit - head->read;
if (!count) {
@@ -432,10 +434,33 @@
line discipline as we want to empty the queue */
if (test_bit(TTY_FLUSHPENDING, &tty->flags))
break;
+
+ /* update receive room */
+ spin_lock(&tty->read_lock);
+ if (tty->update_room_in_ldisc) {
+ if ((tty->read_cnt == N_TTY_BUF_SIZE - 1) &&
+ (tty->receive_room ==
+ N_TTY_BUF_SIZE - 1))
+ tty->rr_bug++;
+ left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
+ }
+ spin_unlock(&tty->read_lock);
+
if (!tty->receive_room)
break;
- if (count > tty->receive_room)
- count = tty->receive_room;
+
+ if (tty->update_room_in_ldisc && !left) {
+ schedule_work(&tty->buf.work);
+ break;
+ }
+
+ if (tty->update_room_in_ldisc)
+ max_space = min(left, tty->receive_room);
+ else
+ max_space = tty->receive_room;
+
+ if (count > max_space)
+ count = max_space;
char_buf = head->char_buf_ptr + head->read;
flag_buf = head->flag_buf_ptr + head->read;
head->read += count;