|
@@ -81,38 +81,6 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
|
|
return put_user(x, ptr);
|
|
return put_user(x, ptr);
|
|
}
|
|
}
|
|
|
|
|
|
-/**
|
|
|
|
- * n_tty_set__room - receive space
|
|
|
|
- * @tty: terminal
|
|
|
|
- *
|
|
|
|
- * Called by the driver to find out how much data it is
|
|
|
|
- * permitted to feed to the line discipline without any being lost
|
|
|
|
- * and thus to manage flow control. Not serialized. Answers for the
|
|
|
|
- * "instant".
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-static void n_tty_set_room(struct tty_struct *tty)
|
|
|
|
-{
|
|
|
|
- /* tty->read_cnt is not read locked ? */
|
|
|
|
- int left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
|
|
|
|
- int old_left;
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * If we are doing input canonicalization, and there are no
|
|
|
|
- * pending newlines, let characters through without limit, so
|
|
|
|
- * that erase characters will be handled. Other excess
|
|
|
|
- * characters will be beeped.
|
|
|
|
- */
|
|
|
|
- if (left <= 0)
|
|
|
|
- left = tty->icanon && !tty->canon_data;
|
|
|
|
- old_left = tty->receive_room;
|
|
|
|
- tty->receive_room = left;
|
|
|
|
-
|
|
|
|
- /* Did this open up the receive buffer? We may need to flip */
|
|
|
|
- if (left && !old_left)
|
|
|
|
- schedule_work(&tty->buf.work);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
|
|
static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
|
|
{
|
|
{
|
|
if (tty->read_cnt < N_TTY_BUF_SIZE) {
|
|
if (tty->read_cnt < N_TTY_BUF_SIZE) {
|
|
@@ -184,7 +152,6 @@ static void reset_buffer_flags(struct tty_struct *tty)
|
|
|
|
|
|
tty->canon_head = tty->canon_data = tty->erasing = 0;
|
|
tty->canon_head = tty->canon_data = tty->erasing = 0;
|
|
memset(&tty->read_flags, 0, sizeof tty->read_flags);
|
|
memset(&tty->read_flags, 0, sizeof tty->read_flags);
|
|
- n_tty_set_room(tty);
|
|
|
|
check_unthrottle(tty);
|
|
check_unthrottle(tty);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1360,17 +1327,19 @@ static void n_tty_write_wakeup(struct tty_struct *tty)
|
|
* calls one at a time and in order (or using flush_to_ldisc)
|
|
* calls one at a time and in order (or using flush_to_ldisc)
|
|
*/
|
|
*/
|
|
|
|
|
|
-static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|
|
|
- char *fp, int count)
|
|
|
|
|
|
+static unsigned int n_tty_receive_buf(struct tty_struct *tty,
|
|
|
|
+ const unsigned char *cp, char *fp, int count)
|
|
{
|
|
{
|
|
const unsigned char *p;
|
|
const unsigned char *p;
|
|
char *f, flags = TTY_NORMAL;
|
|
char *f, flags = TTY_NORMAL;
|
|
int i;
|
|
int i;
|
|
char buf[64];
|
|
char buf[64];
|
|
unsigned long cpuflags;
|
|
unsigned long cpuflags;
|
|
|
|
+ int left;
|
|
|
|
+ int ret = 0;
|
|
|
|
|
|
if (!tty->read_buf)
|
|
if (!tty->read_buf)
|
|
- return;
|
|
|
|
|
|
+ return 0;
|
|
|
|
|
|
if (tty->real_raw) {
|
|
if (tty->real_raw) {
|
|
spin_lock_irqsave(&tty->read_lock, cpuflags);
|
|
spin_lock_irqsave(&tty->read_lock, cpuflags);
|
|
@@ -1380,6 +1349,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|
memcpy(tty->read_buf + tty->read_head, cp, i);
|
|
memcpy(tty->read_buf + tty->read_head, cp, i);
|
|
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
|
|
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
|
|
tty->read_cnt += i;
|
|
tty->read_cnt += i;
|
|
|
|
+ ret += i;
|
|
cp += i;
|
|
cp += i;
|
|
count -= i;
|
|
count -= i;
|
|
|
|
|
|
@@ -1389,8 +1359,10 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|
memcpy(tty->read_buf + tty->read_head, cp, i);
|
|
memcpy(tty->read_buf + tty->read_head, cp, i);
|
|
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
|
|
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
|
|
tty->read_cnt += i;
|
|
tty->read_cnt += i;
|
|
|
|
+ ret += i;
|
|
spin_unlock_irqrestore(&tty->read_lock, cpuflags);
|
|
spin_unlock_irqrestore(&tty->read_lock, cpuflags);
|
|
} else {
|
|
} else {
|
|
|
|
+ ret = count;
|
|
for (i = count, p = cp, f = fp; i; i--, p++) {
|
|
for (i = count, p = cp, f = fp; i; i--, p++) {
|
|
if (f)
|
|
if (f)
|
|
flags = *f++;
|
|
flags = *f++;
|
|
@@ -1418,8 +1390,6 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|
tty->ops->flush_chars(tty);
|
|
tty->ops->flush_chars(tty);
|
|
}
|
|
}
|
|
|
|
|
|
- n_tty_set_room(tty);
|
|
|
|
-
|
|
|
|
if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
|
|
if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
|
|
L_EXTPROC(tty)) {
|
|
L_EXTPROC(tty)) {
|
|
kill_fasync(&tty->fasync, SIGIO, POLL_IN);
|
|
kill_fasync(&tty->fasync, SIGIO, POLL_IN);
|
|
@@ -1432,8 +1402,12 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|
* mode. We don't want to throttle the driver if we're in
|
|
* mode. We don't want to throttle the driver if we're in
|
|
* canonical mode and don't have a newline yet!
|
|
* canonical mode and don't have a newline yet!
|
|
*/
|
|
*/
|
|
- if (tty->receive_room < TTY_THRESHOLD_THROTTLE)
|
|
|
|
|
|
+ left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
|
|
|
|
+
|
|
|
|
+ if (left < TTY_THRESHOLD_THROTTLE)
|
|
tty_throttle(tty);
|
|
tty_throttle(tty);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
int is_ignored(int sig)
|
|
int is_ignored(int sig)
|
|
@@ -1477,7 +1451,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
|
|
if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
|
|
if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
|
|
tty->raw = 1;
|
|
tty->raw = 1;
|
|
tty->real_raw = 1;
|
|
tty->real_raw = 1;
|
|
- n_tty_set_room(tty);
|
|
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
|
|
if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
|
|
@@ -1530,7 +1503,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
|
|
else
|
|
else
|
|
tty->real_raw = 0;
|
|
tty->real_raw = 0;
|
|
}
|
|
}
|
|
- n_tty_set_room(tty);
|
|
|
|
/* The termios change make the tty ready for I/O */
|
|
/* The termios change make the tty ready for I/O */
|
|
wake_up_interruptible(&tty->write_wait);
|
|
wake_up_interruptible(&tty->write_wait);
|
|
wake_up_interruptible(&tty->read_wait);
|
|
wake_up_interruptible(&tty->read_wait);
|
|
@@ -1812,8 +1784,6 @@ do_it_again:
|
|
retval = -ERESTARTSYS;
|
|
retval = -ERESTARTSYS;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- /* FIXME: does n_tty_set_room need locking ? */
|
|
|
|
- n_tty_set_room(tty);
|
|
|
|
timeout = schedule_timeout(timeout);
|
|
timeout = schedule_timeout(timeout);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
@@ -1885,10 +1855,8 @@ do_it_again:
|
|
* longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
|
|
* longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
|
|
* we won't get any more characters.
|
|
* we won't get any more characters.
|
|
*/
|
|
*/
|
|
- if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) {
|
|
|
|
- n_tty_set_room(tty);
|
|
|
|
|
|
+ if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE)
|
|
check_unthrottle(tty);
|
|
check_unthrottle(tty);
|
|
- }
|
|
|
|
|
|
|
|
if (b - buf >= minimum)
|
|
if (b - buf >= minimum)
|
|
break;
|
|
break;
|
|
@@ -1910,7 +1878,6 @@ do_it_again:
|
|
} else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
|
|
} else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
|
|
goto do_it_again;
|
|
goto do_it_again;
|
|
|
|
|
|
- n_tty_set_room(tty);
|
|
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
|