[PATCH 2/9] tty : make n_tty_receive_buf return bytes received in raw mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Matthieu CASTET <castet.matthieu@xxxxxxx>
---
 drivers/tty/n_tty.c |   60 +++++++++++++++++++++++++++++++++-----------------
 1 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index c47cd7e..ed5a976 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -113,13 +113,15 @@ static void n_tty_set_room(struct tty_struct *tty)
 		schedule_work(&tty->buf.work);
 }
 
-static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
+static int put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
 {
 	if (tty->read_cnt < N_TTY_BUF_SIZE) {
 		tty->read_buf[tty->read_head] = c;
 		tty->read_head = (tty->read_head + 1) & (N_TTY_BUF_SIZE-1);
 		tty->read_cnt++;
+		return 1;
 	}
+	return 0;
 }
 
 /**
@@ -127,21 +129,25 @@ static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
  *	@c: character
  *	@tty: tty device
  *
+ *  Report the number of character written
+ *
  *	Add a character to the tty read_buf queue. This is done under the
  *	read_lock to serialize character addition and also to protect us
  *	against parallel reads or flushes
  */
 
-static void put_tty_queue(unsigned char c, struct tty_struct *tty)
+static int put_tty_queue(unsigned char c, struct tty_struct *tty)
 {
 	unsigned long flags;
+	int ret;
 	/*
 	 *	The problem of stomping on the buffers ends here.
 	 *	Why didn't anyone see this one coming? --AJK
 	*/
 	spin_lock_irqsave(&tty->read_lock, flags);
-	put_tty_queue_nolock(c, tty);
+	ret = put_tty_queue_nolock(c, tty);
 	spin_unlock_irqrestore(&tty->read_lock, flags);
+	return ret;
 }
 
 /**
@@ -1082,26 +1088,12 @@ static inline void n_tty_receive_parity_error(struct tty_struct *tty,
 	wake_up_interruptible(&tty->read_wait);
 }
 
-/**
- *	n_tty_receive_char	-	perform processing
- *	@tty: terminal device
- *	@c: character
- *
- *	Process an individual character of input received from the driver.
- *	This is serialized with respect to itself by the rules for the
- *	driver above.
- */
-
-static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
+static inline void n_tty_receive_char_no_raw(struct tty_struct *tty,
+					      unsigned char c)
 {
 	unsigned long flags;
 	int parmrk;
 
-	if (tty->raw) {
-		put_tty_queue(c, tty);
-		return;
-	}
-
 	if (I_ISTRIP(tty))
 		c &= 0x7f;
 	if (I_IUCLC(tty) && L_IEXTEN(tty))
@@ -1330,6 +1322,25 @@ handle_newline:
 	put_tty_queue(c, tty);
 }
 
+/**
+ *	n_tty_receive_char	-	perform processing
+ *	@tty: terminal device
+ *	@c: character
+ *
+ *	Process an individual character of input received from the driver.
+ *	This is serialized with respect to itself by the rules for the
+ *	driver above.
+ */
+
+static inline int n_tty_receive_char(struct tty_struct *tty, unsigned char c)
+{
+	if (tty->raw) {
+		return put_tty_queue(c, tty);
+	}
+
+	n_tty_receive_char_no_raw(tty, c);
+	return 1;
+}
 
 /**
  *	n_tty_write_wakeup	-	asynchronous I/O notifier
@@ -1367,6 +1378,7 @@ static int n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 	int	i;
 	char	buf[64];
 	unsigned long cpuflags;
+	int received = 0;
 
 	if (!tty->read_buf)
 		return count;
@@ -1381,6 +1393,7 @@ static int n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 		tty->read_cnt += i;
 		cp += i;
 		count -= i;
+		received += i;
 
 		i = min(N_TTY_BUF_SIZE - tty->read_cnt,
 			N_TTY_BUF_SIZE - tty->read_head);
@@ -1388,14 +1401,16 @@ static int n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 		memcpy(tty->read_buf + tty->read_head, cp, i);
 		tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
 		tty->read_cnt += i;
+		received += i;
 		spin_unlock_irqrestore(&tty->read_lock, cpuflags);
 	} else {
 		for (i = count, p = cp, f = fp; i; i--, p++) {
+			int ret = 1;
 			if (f)
 				flags = *f++;
 			switch (flags) {
 			case TTY_NORMAL:
-				n_tty_receive_char(tty, *p);
+				ret = n_tty_receive_char(tty, *p);
 				break;
 			case TTY_BREAK:
 				n_tty_receive_break(tty);
@@ -1412,6 +1427,9 @@ static int n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 				       tty_name(tty, buf), flags);
 				break;
 			}
+			if (ret == 0)
+				break;
+			received++;
 		}
 		if (tty->ops->flush_chars)
 			tty->ops->flush_chars(tty);
@@ -1434,7 +1452,7 @@ static int n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 	if (tty->receive_room < TTY_THRESHOLD_THROTTLE)
 		tty_throttle(tty);
 
-	return count;
+	return received;
 }
 
 int is_ignored(int sig)
-- 
1.7.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux