Commit ba2e68ac authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman

TTY: move ldisc data from tty_struct: read_* and echo_* and canon_* stuff

All the ring-buffers...
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
Acked-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3fe780b3
...@@ -83,6 +83,19 @@ struct n_tty_data { ...@@ -83,6 +83,19 @@ struct n_tty_data {
DECLARE_BITMAP(process_char_map, 256); DECLARE_BITMAP(process_char_map, 256);
DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE); DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE);
char *read_buf;
int read_head;
int read_tail;
int read_cnt;
unsigned char *echo_buf;
unsigned int echo_pos;
unsigned int echo_cnt;
int canon_data;
unsigned long canon_head;
unsigned int canon_column;
}; };
static inline int tty_put_user(struct tty_struct *tty, unsigned char x, static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
...@@ -110,14 +123,14 @@ static void n_tty_set_room(struct tty_struct *tty) ...@@ -110,14 +123,14 @@ static void n_tty_set_room(struct tty_struct *tty)
int left; int left;
int old_left; int old_left;
/* tty->read_cnt is not read locked ? */ /* ldata->read_cnt is not read locked ? */
if (I_PARMRK(tty)) { if (I_PARMRK(tty)) {
/* Multiply read_cnt by 3, since each byte might take up to /* Multiply read_cnt by 3, since each byte might take up to
* three times as many spaces when PARMRK is set (depending on * three times as many spaces when PARMRK is set (depending on
* its flags, e.g. parity error). */ * its flags, e.g. parity error). */
left = N_TTY_BUF_SIZE - tty->read_cnt * 3 - 1; left = N_TTY_BUF_SIZE - ldata->read_cnt * 3 - 1;
} else } else
left = N_TTY_BUF_SIZE - tty->read_cnt - 1; left = N_TTY_BUF_SIZE - ldata->read_cnt - 1;
/* /*
* If we are doing input canonicalization, and there are no * If we are doing input canonicalization, and there are no
...@@ -126,7 +139,7 @@ static void n_tty_set_room(struct tty_struct *tty) ...@@ -126,7 +139,7 @@ static void n_tty_set_room(struct tty_struct *tty)
* characters will be beeped. * characters will be beeped.
*/ */
if (left <= 0) if (left <= 0)
left = ldata->icanon && !tty->canon_data; left = ldata->icanon && !ldata->canon_data;
old_left = tty->receive_room; old_left = tty->receive_room;
tty->receive_room = left; tty->receive_room = left;
...@@ -137,10 +150,12 @@ static void n_tty_set_room(struct tty_struct *tty) ...@@ -137,10 +150,12 @@ static void n_tty_set_room(struct tty_struct *tty)
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) { struct n_tty_data *ldata = tty->disc_data;
tty->read_buf[tty->read_head] = c;
tty->read_head = (tty->read_head + 1) & (N_TTY_BUF_SIZE-1); if (ldata->read_cnt < N_TTY_BUF_SIZE) {
tty->read_cnt++; ldata->read_buf[ldata->read_head] = c;
ldata->read_head = (ldata->read_head + 1) & (N_TTY_BUF_SIZE-1);
ldata->read_cnt++;
} }
} }
...@@ -198,14 +213,14 @@ static void reset_buffer_flags(struct tty_struct *tty) ...@@ -198,14 +213,14 @@ static void reset_buffer_flags(struct tty_struct *tty)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&tty->read_lock, flags); spin_lock_irqsave(&tty->read_lock, flags);
tty->read_head = tty->read_tail = tty->read_cnt = 0; ldata->read_head = ldata->read_tail = ldata->read_cnt = 0;
spin_unlock_irqrestore(&tty->read_lock, flags); spin_unlock_irqrestore(&tty->read_lock, flags);
mutex_lock(&tty->echo_lock); mutex_lock(&tty->echo_lock);
tty->echo_pos = tty->echo_cnt = ldata->echo_overrun = 0; ldata->echo_pos = ldata->echo_cnt = ldata->echo_overrun = 0;
mutex_unlock(&tty->echo_lock); mutex_unlock(&tty->echo_lock);
tty->canon_head = tty->canon_data = ldata->erasing = 0; ldata->canon_head = ldata->canon_data = ldata->erasing = 0;
bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
n_tty_set_room(tty); n_tty_set_room(tty);
} }
...@@ -257,11 +272,11 @@ static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) ...@@ -257,11 +272,11 @@ static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
spin_lock_irqsave(&tty->read_lock, flags); spin_lock_irqsave(&tty->read_lock, flags);
if (!ldata->icanon) { if (!ldata->icanon) {
n = tty->read_cnt; n = ldata->read_cnt;
} else if (tty->canon_data) { } else if (ldata->canon_data) {
n = (tty->canon_head > tty->read_tail) ? n = (ldata->canon_head > ldata->read_tail) ?
tty->canon_head - tty->read_tail : ldata->canon_head - ldata->read_tail :
tty->canon_head + (N_TTY_BUF_SIZE - tty->read_tail); ldata->canon_head + (N_TTY_BUF_SIZE - ldata->read_tail);
} }
spin_unlock_irqrestore(&tty->read_lock, flags); spin_unlock_irqrestore(&tty->read_lock, flags);
return n; return n;
...@@ -331,11 +346,11 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space) ...@@ -331,11 +346,11 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
if (O_ONLCR(tty)) { if (O_ONLCR(tty)) {
if (space < 2) if (space < 2)
return -1; return -1;
tty->canon_column = ldata->column = 0; ldata->canon_column = ldata->column = 0;
tty->ops->write(tty, "\r\n", 2); tty->ops->write(tty, "\r\n", 2);
return 2; return 2;
} }
tty->canon_column = ldata->column; ldata->canon_column = ldata->column;
break; break;
case '\r': case '\r':
if (O_ONOCR(tty) && ldata->column == 0) if (O_ONOCR(tty) && ldata->column == 0)
...@@ -343,10 +358,10 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space) ...@@ -343,10 +358,10 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
if (O_OCRNL(tty)) { if (O_OCRNL(tty)) {
c = '\n'; c = '\n';
if (O_ONLRET(tty)) if (O_ONLRET(tty))
tty->canon_column = ldata->column = 0; ldata->canon_column = ldata->column = 0;
break; break;
} }
tty->canon_column = ldata->column = 0; ldata->canon_column = ldata->column = 0;
break; break;
case '\t': case '\t':
spaces = 8 - (ldata->column & 7); spaces = 8 - (ldata->column & 7);
...@@ -453,14 +468,14 @@ static ssize_t process_output_block(struct tty_struct *tty, ...@@ -453,14 +468,14 @@ static ssize_t process_output_block(struct tty_struct *tty,
ldata->column = 0; ldata->column = 0;
if (O_ONLCR(tty)) if (O_ONLCR(tty))
goto break_out; goto break_out;
tty->canon_column = ldata->column; ldata->canon_column = ldata->column;
break; break;
case '\r': case '\r':
if (O_ONOCR(tty) && ldata->column == 0) if (O_ONOCR(tty) && ldata->column == 0)
goto break_out; goto break_out;
if (O_OCRNL(tty)) if (O_OCRNL(tty))
goto break_out; goto break_out;
tty->canon_column = ldata->column = 0; ldata->canon_column = ldata->column = 0;
break; break;
case '\t': case '\t':
goto break_out; goto break_out;
...@@ -518,7 +533,7 @@ static void process_echoes(struct tty_struct *tty) ...@@ -518,7 +533,7 @@ static void process_echoes(struct tty_struct *tty)
unsigned char c; unsigned char c;
unsigned char *cp, *buf_end; unsigned char *cp, *buf_end;
if (!tty->echo_cnt) if (!ldata->echo_cnt)
return; return;
mutex_lock(&tty->output_lock); mutex_lock(&tty->output_lock);
...@@ -526,9 +541,9 @@ static void process_echoes(struct tty_struct *tty) ...@@ -526,9 +541,9 @@ static void process_echoes(struct tty_struct *tty)
space = tty_write_room(tty); space = tty_write_room(tty);
buf_end = tty->echo_buf + N_TTY_BUF_SIZE; buf_end = ldata->echo_buf + N_TTY_BUF_SIZE;
cp = tty->echo_buf + tty->echo_pos; cp = ldata->echo_buf + ldata->echo_pos;
nr = tty->echo_cnt; nr = ldata->echo_cnt;
while (nr > 0) { while (nr > 0) {
c = *cp; c = *cp;
if (c == ECHO_OP_START) { if (c == ECHO_OP_START) {
...@@ -565,7 +580,7 @@ static void process_echoes(struct tty_struct *tty) ...@@ -565,7 +580,7 @@ static void process_echoes(struct tty_struct *tty)
* Otherwise, tab spacing is normal. * Otherwise, tab spacing is normal.
*/ */
if (!(num_chars & 0x80)) if (!(num_chars & 0x80))
num_chars += tty->canon_column; num_chars += ldata->canon_column;
num_bs = 8 - (num_chars & 7); num_bs = 8 - (num_chars & 7);
if (num_bs > space) { if (num_bs > space) {
...@@ -583,7 +598,7 @@ static void process_echoes(struct tty_struct *tty) ...@@ -583,7 +598,7 @@ static void process_echoes(struct tty_struct *tty)
break; break;
case ECHO_OP_SET_CANON_COL: case ECHO_OP_SET_CANON_COL:
tty->canon_column = ldata->column; ldata->canon_column = ldata->column;
cp += 2; cp += 2;
nr -= 2; nr -= 2;
break; break;
...@@ -655,14 +670,14 @@ static void process_echoes(struct tty_struct *tty) ...@@ -655,14 +670,14 @@ static void process_echoes(struct tty_struct *tty)
} }
if (nr == 0) { if (nr == 0) {
tty->echo_pos = 0; ldata->echo_pos = 0;
tty->echo_cnt = 0; ldata->echo_cnt = 0;
ldata->echo_overrun = 0; ldata->echo_overrun = 0;
} else { } else {
int num_processed = tty->echo_cnt - nr; int num_processed = ldata->echo_cnt - nr;
tty->echo_pos += num_processed; ldata->echo_pos += num_processed;
tty->echo_pos &= N_TTY_BUF_SIZE - 1; ldata->echo_pos &= N_TTY_BUF_SIZE - 1;
tty->echo_cnt = nr; ldata->echo_cnt = nr;
if (num_processed > 0) if (num_processed > 0)
ldata->echo_overrun = 0; ldata->echo_overrun = 0;
} }
...@@ -689,37 +704,37 @@ static void add_echo_byte(unsigned char c, struct tty_struct *tty) ...@@ -689,37 +704,37 @@ static void add_echo_byte(unsigned char c, struct tty_struct *tty)
struct n_tty_data *ldata = tty->disc_data; struct n_tty_data *ldata = tty->disc_data;
int new_byte_pos; int new_byte_pos;
if (tty->echo_cnt == N_TTY_BUF_SIZE) { if (ldata->echo_cnt == N_TTY_BUF_SIZE) {
/* Circular buffer is already at capacity */ /* Circular buffer is already at capacity */
new_byte_pos = tty->echo_pos; new_byte_pos = ldata->echo_pos;
/* /*
* Since the buffer start position needs to be advanced, * Since the buffer start position needs to be advanced,
* be sure to step by a whole operation byte group. * be sure to step by a whole operation byte group.
*/ */
if (tty->echo_buf[tty->echo_pos] == ECHO_OP_START) { if (ldata->echo_buf[ldata->echo_pos] == ECHO_OP_START) {
if (tty->echo_buf[(tty->echo_pos + 1) & if (ldata->echo_buf[(ldata->echo_pos + 1) &
(N_TTY_BUF_SIZE - 1)] == (N_TTY_BUF_SIZE - 1)] ==
ECHO_OP_ERASE_TAB) { ECHO_OP_ERASE_TAB) {
tty->echo_pos += 3; ldata->echo_pos += 3;
tty->echo_cnt -= 2; ldata->echo_cnt -= 2;
} else { } else {
tty->echo_pos += 2; ldata->echo_pos += 2;
tty->echo_cnt -= 1; ldata->echo_cnt -= 1;
} }
} else { } else {
tty->echo_pos++; ldata->echo_pos++;
} }
tty->echo_pos &= N_TTY_BUF_SIZE - 1; ldata->echo_pos &= N_TTY_BUF_SIZE - 1;
ldata->echo_overrun = 1; ldata->echo_overrun = 1;
} else { } else {
new_byte_pos = tty->echo_pos + tty->echo_cnt; new_byte_pos = ldata->echo_pos + ldata->echo_cnt;
new_byte_pos &= N_TTY_BUF_SIZE - 1; new_byte_pos &= N_TTY_BUF_SIZE - 1;
tty->echo_cnt++; ldata->echo_cnt++;
} }
tty->echo_buf[new_byte_pos] = c; ldata->echo_buf[new_byte_pos] = c;
} }
/** /**
...@@ -889,7 +904,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) ...@@ -889,7 +904,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
unsigned long flags; unsigned long flags;
/* FIXME: locking needed ? */ /* FIXME: locking needed ? */
if (tty->read_head == tty->canon_head) { if (ldata->read_head == ldata->canon_head) {
/* process_output('\a', tty); */ /* what do you think? */ /* process_output('\a', tty); */ /* what do you think? */
return; return;
} }
...@@ -900,17 +915,17 @@ static void eraser(unsigned char c, struct tty_struct *tty) ...@@ -900,17 +915,17 @@ static void eraser(unsigned char c, struct tty_struct *tty)
else { else {
if (!L_ECHO(tty)) { if (!L_ECHO(tty)) {
spin_lock_irqsave(&tty->read_lock, flags); spin_lock_irqsave(&tty->read_lock, flags);
tty->read_cnt -= ((tty->read_head - tty->canon_head) & ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) &
(N_TTY_BUF_SIZE - 1)); (N_TTY_BUF_SIZE - 1));
tty->read_head = tty->canon_head; ldata->read_head = ldata->canon_head;
spin_unlock_irqrestore(&tty->read_lock, flags); spin_unlock_irqrestore(&tty->read_lock, flags);
return; return;
} }
if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) { if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) {
spin_lock_irqsave(&tty->read_lock, flags); spin_lock_irqsave(&tty->read_lock, flags);
tty->read_cnt -= ((tty->read_head - tty->canon_head) & ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) &
(N_TTY_BUF_SIZE - 1)); (N_TTY_BUF_SIZE - 1));
tty->read_head = tty->canon_head; ldata->read_head = ldata->canon_head;
spin_unlock_irqrestore(&tty->read_lock, flags); spin_unlock_irqrestore(&tty->read_lock, flags);
finish_erasing(tty); finish_erasing(tty);
echo_char(KILL_CHAR(tty), tty); echo_char(KILL_CHAR(tty), tty);
...@@ -924,14 +939,14 @@ static void eraser(unsigned char c, struct tty_struct *tty) ...@@ -924,14 +939,14 @@ static void eraser(unsigned char c, struct tty_struct *tty)
seen_alnums = 0; seen_alnums = 0;
/* FIXME: Locking ?? */ /* FIXME: Locking ?? */
while (tty->read_head != tty->canon_head) { while (ldata->read_head != ldata->canon_head) {
head = tty->read_head; head = ldata->read_head;
/* erase a single possibly multibyte character */ /* erase a single possibly multibyte character */
do { do {
head = (head - 1) & (N_TTY_BUF_SIZE-1); head = (head - 1) & (N_TTY_BUF_SIZE-1);
c = tty->read_buf[head]; c = ldata->read_buf[head];
} while (is_continuation(c, tty) && head != tty->canon_head); } while (is_continuation(c, tty) && head != ldata->canon_head);
/* do not partially erase */ /* do not partially erase */
if (is_continuation(c, tty)) if (is_continuation(c, tty))
...@@ -944,10 +959,10 @@ static void eraser(unsigned char c, struct tty_struct *tty) ...@@ -944,10 +959,10 @@ static void eraser(unsigned char c, struct tty_struct *tty)
else if (seen_alnums) else if (seen_alnums)
break; break;
} }
cnt = (tty->read_head - head) & (N_TTY_BUF_SIZE-1); cnt = (ldata->read_head - head) & (N_TTY_BUF_SIZE-1);
spin_lock_irqsave(&tty->read_lock, flags); spin_lock_irqsave(&tty->read_lock, flags);
tty->read_head = head; ldata->read_head = head;
tty->read_cnt -= cnt; ldata->read_cnt -= cnt;
spin_unlock_irqrestore(&tty->read_lock, flags); spin_unlock_irqrestore(&tty->read_lock, flags);
if (L_ECHO(tty)) { if (L_ECHO(tty)) {
if (L_ECHOPRT(tty)) { if (L_ECHOPRT(tty)) {
...@@ -959,7 +974,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) ...@@ -959,7 +974,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
echo_char(c, tty); echo_char(c, tty);
while (--cnt > 0) { while (--cnt > 0) {
head = (head+1) & (N_TTY_BUF_SIZE-1); head = (head+1) & (N_TTY_BUF_SIZE-1);
echo_char_raw(tty->read_buf[head], tty); echo_char_raw(ldata->read_buf[head], tty);
echo_move_back_col(tty); echo_move_back_col(tty);
} }
} else if (kill_type == ERASE && !L_ECHOE(tty)) { } else if (kill_type == ERASE && !L_ECHOE(tty)) {
...@@ -967,7 +982,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) ...@@ -967,7 +982,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
} else if (c == '\t') { } else if (c == '\t') {
unsigned int num_chars = 0; unsigned int num_chars = 0;
int after_tab = 0; int after_tab = 0;
unsigned long tail = tty->read_head; unsigned long tail = ldata->read_head;
/* /*
* Count the columns used for characters * Count the columns used for characters
...@@ -976,9 +991,9 @@ static void eraser(unsigned char c, struct tty_struct *tty) ...@@ -976,9 +991,9 @@ static void eraser(unsigned char c, struct tty_struct *tty)
* This info is used to go back the correct * This info is used to go back the correct
* number of columns. * number of columns.
*/ */
while (tail != tty->canon_head) { while (tail != ldata->canon_head) {
tail = (tail-1) & (N_TTY_BUF_SIZE-1); tail = (tail-1) & (N_TTY_BUF_SIZE-1);
c = tty->read_buf[tail]; c = ldata->read_buf[tail];
if (c == '\t') { if (c == '\t') {
after_tab = 1; after_tab = 1;
break; break;
...@@ -1006,7 +1021,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) ...@@ -1006,7 +1021,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
if (kill_type == ERASE) if (kill_type == ERASE)
break; break;
} }
if (tty->read_head == tty->canon_head && L_ECHO(tty)) if (ldata->read_head == ldata->canon_head && L_ECHO(tty))
finish_erasing(tty); finish_erasing(tty);
} }
...@@ -1171,7 +1186,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) ...@@ -1171,7 +1186,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
if (!test_bit(c, ldata->process_char_map) || ldata->lnext) { if (!test_bit(c, ldata->process_char_map) || ldata->lnext) {
ldata->lnext = 0; ldata->lnext = 0;
parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
/* beep if no space */ /* beep if no space */
if (L_ECHO(tty)) if (L_ECHO(tty))
process_output('\a', tty); process_output('\a', tty);
...@@ -1180,7 +1195,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) ...@@ -1180,7 +1195,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
if (L_ECHO(tty)) { if (L_ECHO(tty)) {
finish_erasing(tty); finish_erasing(tty);
/* Record the column of first canon char. */ /* Record the column of first canon char. */
if (tty->canon_head == tty->read_head) if (ldata->canon_head == ldata->read_head)
echo_set_canon_col(tty); echo_set_canon_col(tty);
echo_char(c, tty); echo_char(c, tty);
process_echoes(tty); process_echoes(tty);
...@@ -1264,20 +1279,20 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) ...@@ -1264,20 +1279,20 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
} }
if (c == REPRINT_CHAR(tty) && L_ECHO(tty) && if (c == REPRINT_CHAR(tty) && L_ECHO(tty) &&
L_IEXTEN(tty)) { L_IEXTEN(tty)) {
unsigned long tail = tty->canon_head; unsigned long tail = ldata->canon_head;
finish_erasing(tty); finish_erasing(tty);
echo_char(c, tty); echo_char(c, tty);
echo_char_raw('\n', tty); echo_char_raw('\n', tty);
while (tail != tty->read_head) { while (tail != ldata->read_head) {
echo_char(tty->read_buf[tail], tty); echo_char(ldata->read_buf[tail], tty);
tail = (tail+1) & (N_TTY_BUF_SIZE-1); tail = (tail+1) & (N_TTY_BUF_SIZE-1);
} }
process_echoes(tty); process_echoes(tty);
return; return;
} }
if (c == '\n') { if (c == '\n') {
if (tty->read_cnt >= N_TTY_BUF_SIZE) { if (ldata->read_cnt >= N_TTY_BUF_SIZE) {
if (L_ECHO(tty)) if (L_ECHO(tty))
process_output('\a', tty); process_output('\a', tty);
return; return;
...@@ -1289,9 +1304,9 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) ...@@ -1289,9 +1304,9 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
goto handle_newline; goto handle_newline;
} }
if (c == EOF_CHAR(tty)) { if (c == EOF_CHAR(tty)) {
if (tty->read_cnt >= N_TTY_BUF_SIZE) if (ldata->read_cnt >= N_TTY_BUF_SIZE)
return; return;
if (tty->canon_head != tty->read_head) if (ldata->canon_head != ldata->read_head)
set_bit(TTY_PUSH, &tty->flags); set_bit(TTY_PUSH, &tty->flags);
c = __DISABLED_CHAR; c = __DISABLED_CHAR;
goto handle_newline; goto handle_newline;
...@@ -1300,7 +1315,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) ...@@ -1300,7 +1315,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
(c == EOL2_CHAR(tty) && L_IEXTEN(tty))) { (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty))
? 1 : 0; ? 1 : 0;
if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) { if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) {
if (L_ECHO(tty)) if (L_ECHO(tty))
process_output('\a', tty); process_output('\a', tty);
return; return;
...@@ -1310,7 +1325,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) ...@@ -1310,7 +1325,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
*/ */
if (L_ECHO(tty)) { if (L_ECHO(tty)) {
/* Record the column of first canon char. */ /* Record the column of first canon char. */
if (tty->canon_head == tty->read_head) if (ldata->canon_head == ldata->read_head)
echo_set_canon_col(tty); echo_set_canon_col(tty);
echo_char(c, tty); echo_char(c, tty);
process_echoes(tty); process_echoes(tty);
...@@ -1324,10 +1339,10 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) ...@@ -1324,10 +1339,10 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
handle_newline: handle_newline:
spin_lock_irqsave(&tty->read_lock, flags); spin_lock_irqsave(&tty->read_lock, flags);
set_bit(tty->read_head, ldata->read_flags); set_bit(ldata->read_head, ldata->read_flags);
put_tty_queue_nolock(c, tty); put_tty_queue_nolock(c, tty);
tty->canon_head = tty->read_head; ldata->canon_head = ldata->read_head;
tty->canon_data++; ldata->canon_data++;
spin_unlock_irqrestore(&tty->read_lock, flags); spin_unlock_irqrestore(&tty->read_lock, flags);
kill_fasync(&tty->fasync, SIGIO, POLL_IN); kill_fasync(&tty->fasync, SIGIO, POLL_IN);
if (waitqueue_active(&tty->read_wait)) if (waitqueue_active(&tty->read_wait))
...@@ -1337,7 +1352,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) ...@@ -1337,7 +1352,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
} }
parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
/* beep if no space */ /* beep if no space */
if (L_ECHO(tty)) if (L_ECHO(tty))
process_output('\a', tty); process_output('\a', tty);
...@@ -1349,7 +1364,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) ...@@ -1349,7 +1364,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
echo_char_raw('\n', tty); echo_char_raw('\n', tty);
else { else {
/* Record the column of first canon char. */ /* Record the column of first canon char. */
if (tty->canon_head == tty->read_head) if (ldata->canon_head == ldata->read_head)
echo_set_canon_col(tty); echo_set_canon_col(tty);
echo_char(c, tty); echo_char(c, tty);
} }
...@@ -1403,21 +1418,21 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, ...@@ -1403,21 +1418,21 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
if (ldata->real_raw) { if (ldata->real_raw) {
spin_lock_irqsave(&tty->read_lock, cpuflags); spin_lock_irqsave(&tty->read_lock, cpuflags);
i = min(N_TTY_BUF_SIZE - tty->read_cnt, i = min(N_TTY_BUF_SIZE - ldata->read_cnt,
N_TTY_BUF_SIZE - tty->read_head); N_TTY_BUF_SIZE - ldata->read_head);
i = min(count, i); i = min(count, i);
memcpy(tty->read_buf + tty->read_head, cp, i); memcpy(ldata->read_buf + ldata->read_head, cp, i);
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1);
tty->read_cnt += i; ldata->read_cnt += i;
cp += i; cp += i;
count -= i; count -= i;
i = min(N_TTY_BUF_SIZE - tty->read_cnt, i = min(N_TTY_BUF_SIZE - ldata->read_cnt,
N_TTY_BUF_SIZE - tty->read_head); N_TTY_BUF_SIZE - ldata->read_head);
i = min(count, i); i = min(count, i);
memcpy(tty->read_buf + tty->read_head, cp, i); memcpy(ldata->read_buf + ldata->read_head, cp, i);
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1);
tty->read_cnt += i; ldata->read_cnt += i;
spin_unlock_irqrestore(&tty->read_lock, cpuflags); spin_unlock_irqrestore(&tty->read_lock, cpuflags);
} else { } else {
for (i = count, p = cp, f = fp; i; i--, p++) { for (i = count, p = cp, f = fp; i; i--, p++) {
...@@ -1449,7 +1464,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, ...@@ -1449,7 +1464,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
n_tty_set_room(tty); n_tty_set_room(tty);
if ((!ldata->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || if ((!ldata->icanon && (ldata->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);
if (waitqueue_active(&tty->read_wait)) if (waitqueue_active(&tty->read_wait))
...@@ -1500,12 +1515,12 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) ...@@ -1500,12 +1515,12 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON; canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON;
if (canon_change) { if (canon_change) {
bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
tty->canon_head = tty->read_tail; ldata->canon_head = ldata->read_tail;
tty->canon_data = 0; ldata->canon_data = 0;
ldata->erasing = 0; ldata->erasing = 0;
} }
if (canon_change && !L_ICANON(tty) && tty->read_cnt) if (canon_change && !L_ICANON(tty) && ldata->read_cnt)
wake_up_interruptible(&tty->read_wait); wake_up_interruptible(&tty->read_wait);
ldata->icanon = (L_ICANON(tty) != 0); ldata->icanon = (L_ICANON(tty) != 0);
...@@ -1586,11 +1601,9 @@ static void n_tty_close(struct tty_struct *tty) ...@@ -1586,11 +1601,9 @@ static void n_tty_close(struct tty_struct *tty)
struct n_tty_data *ldata = tty->disc_data; struct n_tty_data *ldata = tty->disc_data;
n_tty_flush_buffer(tty); n_tty_flush_buffer(tty);
kfree(tty->read_buf); kfree(ldata->read_buf);
kfree(tty->echo_buf); kfree(ldata->echo_buf);
kfree(ldata); kfree(ldata);
tty->read_buf = NULL;
tty->echo_buf = NULL;
tty->disc_data = NULL; tty->disc_data = NULL;
} }
...@@ -1615,9 +1628,9 @@ static int n_tty_open(struct tty_struct *tty) ...@@ -1615,9 +1628,9 @@ static int n_tty_open(struct tty_struct *tty)
ldata->overrun_time = jiffies; ldata->overrun_time = jiffies;
/* These are ugly. Currently a malloc failure here can panic */ /* These are ugly. Currently a malloc failure here can panic */
tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); ldata->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
tty->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); ldata->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
if (!tty->read_buf || !tty->echo_buf) if (!ldata->read_buf || !ldata->echo_buf)
goto err_free_bufs; goto err_free_bufs;
tty->disc_data = ldata; tty->disc_data = ldata;
...@@ -1630,8 +1643,8 @@ static int n_tty_open(struct tty_struct *tty) ...@@ -1630,8 +1643,8 @@ static int n_tty_open(struct tty_struct *tty)
return 0; return 0;
err_free_bufs: err_free_bufs:
kfree(tty->read_buf); kfree(ldata->read_buf);
kfree(tty->echo_buf); kfree(ldata->echo_buf);
kfree(ldata); kfree(ldata);
err: err:
return -ENOMEM; return -ENOMEM;
...@@ -1643,9 +1656,9 @@ static inline int input_available_p(struct tty_struct *tty, int amt) ...@@ -1643,9 +1656,9 @@ static inline int input_available_p(struct tty_struct *tty, int amt)
tty_flush_to_ldisc(tty); tty_flush_to_ldisc(tty);
if (ldata->icanon && !L_EXTPROC(tty)) { if (ldata->icanon && !L_EXTPROC(tty)) {
if (tty->canon_data) if (ldata->canon_data)
return 1; return 1;
} else if (tty->read_cnt >= (amt ? amt : 1)) } else if (ldata->read_cnt >= (amt ? amt : 1))
return 1; return 1;
return 0; return 0;
...@@ -1681,21 +1694,21 @@ static int copy_from_read_buf(struct tty_struct *tty, ...@@ -1681,21 +1694,21 @@ static int copy_from_read_buf(struct tty_struct *tty,
retval = 0; retval = 0;
spin_lock_irqsave(&tty->read_lock, flags); spin_lock_irqsave(&tty->read_lock, flags);
n = min(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail); n = min(ldata->read_cnt, N_TTY_BUF_SIZE - ldata->read_tail);
n = min(*nr, n); n = min(*nr, n);
spin_unlock_irqrestore(&tty->read_lock, flags); spin_unlock_irqrestore(&tty->read_lock, flags);
if (n) { if (n) {
retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n); retval = copy_to_user(*b, &ldata->read_buf[ldata->read_tail], n);
n -= retval; n -= retval;
is_eof = n == 1 && is_eof = n == 1 &&
tty->read_buf[tty->read_tail] == EOF_CHAR(tty); ldata->read_buf[ldata->read_tail] == EOF_CHAR(tty);
tty_audit_add_data(tty, &tty->read_buf[tty->read_tail], n, tty_audit_add_data(tty, &ldata->read_buf[ldata->read_tail], n,
ldata->icanon); ldata->icanon);
spin_lock_irqsave(&tty->read_lock, flags); spin_lock_irqsave(&tty->read_lock, flags);
tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); ldata->read_tail = (ldata->read_tail + n) & (N_TTY_BUF_SIZE-1);
tty->read_cnt -= n; ldata->read_cnt -= n;
/* Turn single EOF into zero-length read */ /* Turn single EOF into zero-length read */
if (L_EXTPROC(tty) && ldata->icanon && is_eof && !tty->read_cnt) if (L_EXTPROC(tty) && ldata->icanon && is_eof && !ldata->read_cnt)
n = 0; n = 0;
spin_unlock_irqrestore(&tty->read_lock, flags); spin_unlock_irqrestore(&tty->read_lock, flags);
*b += n; *b += n;
...@@ -1878,22 +1891,22 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, ...@@ -1878,22 +1891,22 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
if (ldata->icanon && !L_EXTPROC(tty)) { if (ldata->icanon && !L_EXTPROC(tty)) {
/* N.B. avoid overrun if nr == 0 */ /* N.B. avoid overrun if nr == 0 */
spin_lock_irqsave(&tty->read_lock, flags); spin_lock_irqsave(&tty->read_lock, flags);
while (nr && tty->read_cnt) { while (nr && ldata->read_cnt) {
int eol; int eol;
eol = test_and_clear_bit(tty->read_tail, eol = test_and_clear_bit(ldata->read_tail,
ldata->read_flags); ldata->read_flags);
c = tty->read_buf[tty->read_tail]; c = ldata->read_buf[ldata->read_tail];
tty->read_tail = ((tty->read_tail+1) & ldata->read_tail = ((ldata->read_tail+1) &
(N_TTY_BUF_SIZE-1)); (N_TTY_BUF_SIZE-1));
tty->read_cnt--; ldata->read_cnt--;
if (eol) { if (eol) {
/* this test should be redundant: /* this test should be redundant:
* we shouldn't be reading data if * we shouldn't be reading data if
* canon_data is 0 * canon_data is 0
*/ */
if (--tty->canon_data < 0) if (--ldata->canon_data < 0)
tty->canon_data = 0; ldata->canon_data = 0;
} }
spin_unlock_irqrestore(&tty->read_lock, flags); spin_unlock_irqrestore(&tty->read_lock, flags);
...@@ -2111,15 +2124,15 @@ static unsigned long inq_canon(struct tty_struct *tty) ...@@ -2111,15 +2124,15 @@ static unsigned long inq_canon(struct tty_struct *tty)
struct n_tty_data *ldata = tty->disc_data; struct n_tty_data *ldata = tty->disc_data;
int nr, head, tail; int nr, head, tail;
if (!tty->canon_data) if (!ldata->canon_data)
return 0; return 0;
head = tty->canon_head; head = ldata->canon_head;
tail = tty->read_tail; tail = ldata->read_tail;
nr = (head - tail) & (N_TTY_BUF_SIZE-1); nr = (head - tail) & (N_TTY_BUF_SIZE-1);
/* Skip EOF-chars.. */ /* Skip EOF-chars.. */
while (head != tail) { while (head != tail) {
if (test_bit(tail, ldata->read_flags) && if (test_bit(tail, ldata->read_flags) &&
tty->read_buf[tail] == __DISABLED_CHAR) ldata->read_buf[tail] == __DISABLED_CHAR)
nr--; nr--;
tail = (tail+1) & (N_TTY_BUF_SIZE-1); tail = (tail+1) & (N_TTY_BUF_SIZE-1);
} }
...@@ -2129,6 +2142,7 @@ static unsigned long inq_canon(struct tty_struct *tty) ...@@ -2129,6 +2142,7 @@ static unsigned long inq_canon(struct tty_struct *tty)
static int n_tty_ioctl(struct tty_struct *tty, struct file *file, static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
struct n_tty_data *ldata = tty->disc_data;
int retval; int retval;
switch (cmd) { switch (cmd) {
...@@ -2136,7 +2150,7 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file, ...@@ -2136,7 +2150,7 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
return put_user(tty_chars_in_buffer(tty), (int __user *) arg); return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
case TIOCINQ: case TIOCINQ:
/* FIXME: Locking */ /* FIXME: Locking */
retval = tty->read_cnt; retval = ldata->read_cnt;
if (L_ICANON(tty)) if (L_ICANON(tty))
retval = inq_canon(tty); retval = inq_canon(tty);
return put_user(retval, (unsigned int __user *) arg); return put_user(retval, (unsigned int __user *) arg);
......
...@@ -272,16 +272,6 @@ struct tty_struct { ...@@ -272,16 +272,6 @@ struct tty_struct {
*/ */
unsigned char closing:1; unsigned char closing:1;
unsigned short minimum_to_wake; unsigned short minimum_to_wake;
char *read_buf;
int read_head;
int read_tail;
int read_cnt;
unsigned char *echo_buf;
unsigned int echo_pos;
unsigned int echo_cnt;
int canon_data;
unsigned long canon_head;
unsigned int canon_column;
struct mutex atomic_read_lock; struct mutex atomic_read_lock;
struct mutex atomic_write_lock; struct mutex atomic_write_lock;
struct mutex output_lock; struct mutex output_lock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment