TTY: n_tty, propagate n_tty_data

In some funtions we need only n_tty_data, so pass it down directly in
case tty is not needed there.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Jiri Slaby 2012-10-18 22:26:43 +02:00 committed by Greg Kroah-Hartman
parent bddc7152f6
commit 57c941212d

View file

@ -153,10 +153,8 @@ static void n_tty_set_room(struct tty_struct *tty)
schedule_work(&tty->buf.work); 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 n_tty_data *ldata)
{ {
struct n_tty_data *ldata = tty->disc_data;
if (ldata->read_cnt < N_TTY_BUF_SIZE) { if (ldata->read_cnt < N_TTY_BUF_SIZE) {
ldata->read_buf[ldata->read_head] = c; ldata->read_buf[ldata->read_head] = c;
ldata->read_head = (ldata->read_head + 1) & (N_TTY_BUF_SIZE-1); ldata->read_head = (ldata->read_head + 1) & (N_TTY_BUF_SIZE-1);
@ -167,23 +165,22 @@ static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
/** /**
* put_tty_queue - add character to tty * put_tty_queue - add character to tty
* @c: character * @c: character
* @tty: tty device * @ldata: n_tty data
* *
* Add a character to the tty read_buf queue. This is done under the * 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 * read_lock to serialize character addition and also to protect us
* against parallel reads or flushes * against parallel reads or flushes
*/ */
static void put_tty_queue(unsigned char c, struct tty_struct *tty) static void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
{ {
struct n_tty_data *ldata = tty->disc_data;
unsigned long flags; unsigned long flags;
/* /*
* The problem of stomping on the buffers ends here. * The problem of stomping on the buffers ends here.
* Why didn't anyone see this one coming? --AJK * Why didn't anyone see this one coming? --AJK
*/ */
spin_lock_irqsave(&ldata->read_lock, flags); spin_lock_irqsave(&ldata->read_lock, flags);
put_tty_queue_nolock(c, tty); put_tty_queue_nolock(c, ldata);
spin_unlock_irqrestore(&ldata->read_lock, flags); spin_unlock_irqrestore(&ldata->read_lock, flags);
} }
@ -699,16 +696,15 @@ static void process_echoes(struct tty_struct *tty)
/** /**
* add_echo_byte - add a byte to the echo buffer * add_echo_byte - add a byte to the echo buffer
* @c: unicode byte to echo * @c: unicode byte to echo
* @tty: terminal device * @ldata: n_tty data
* *
* Add a character or operation byte to the echo buffer. * Add a character or operation byte to the echo buffer.
* *
* Should be called under the echo lock to protect the echo buffer. * Should be called under the echo lock to protect the echo buffer.
*/ */
static void add_echo_byte(unsigned char c, struct tty_struct *tty) static void add_echo_byte(unsigned char c, struct n_tty_data *ldata)
{ {
struct n_tty_data *ldata = tty->disc_data;
int new_byte_pos; int new_byte_pos;
if (ldata->echo_cnt == N_TTY_BUF_SIZE) { if (ldata->echo_cnt == N_TTY_BUF_SIZE) {
@ -746,28 +742,24 @@ static void add_echo_byte(unsigned char c, struct tty_struct *tty)
/** /**
* echo_move_back_col - add operation to move back a column * echo_move_back_col - add operation to move back a column
* @tty: terminal device * @ldata: n_tty data
* *
* Add an operation to the echo buffer to move back one column. * Add an operation to the echo buffer to move back one column.
* *
* Locking: echo_lock to protect the echo buffer * Locking: echo_lock to protect the echo buffer
*/ */
static void echo_move_back_col(struct tty_struct *tty) static void echo_move_back_col(struct n_tty_data *ldata)
{ {
struct n_tty_data *ldata = tty->disc_data;
mutex_lock(&ldata->echo_lock); mutex_lock(&ldata->echo_lock);
add_echo_byte(ECHO_OP_START, ldata);
add_echo_byte(ECHO_OP_START, tty); add_echo_byte(ECHO_OP_MOVE_BACK_COL, ldata);
add_echo_byte(ECHO_OP_MOVE_BACK_COL, tty);
mutex_unlock(&ldata->echo_lock); mutex_unlock(&ldata->echo_lock);
} }
/** /**
* echo_set_canon_col - add operation to set the canon column * echo_set_canon_col - add operation to set the canon column
* @tty: terminal device * @ldata: n_tty data
* *
* Add an operation to the echo buffer to set the canon column * Add an operation to the echo buffer to set the canon column
* to the current column. * to the current column.
@ -775,15 +767,11 @@ static void echo_move_back_col(struct tty_struct *tty)
* Locking: echo_lock to protect the echo buffer * Locking: echo_lock to protect the echo buffer
*/ */
static void echo_set_canon_col(struct tty_struct *tty) static void echo_set_canon_col(struct n_tty_data *ldata)
{ {
struct n_tty_data *ldata = tty->disc_data;
mutex_lock(&ldata->echo_lock); mutex_lock(&ldata->echo_lock);
add_echo_byte(ECHO_OP_START, ldata);
add_echo_byte(ECHO_OP_START, tty); add_echo_byte(ECHO_OP_SET_CANON_COL, ldata);
add_echo_byte(ECHO_OP_SET_CANON_COL, tty);
mutex_unlock(&ldata->echo_lock); mutex_unlock(&ldata->echo_lock);
} }
@ -791,7 +779,7 @@ static void echo_set_canon_col(struct tty_struct *tty)
* echo_erase_tab - add operation to erase a tab * echo_erase_tab - add operation to erase a tab
* @num_chars: number of character columns already used * @num_chars: number of character columns already used
* @after_tab: true if num_chars starts after a previous tab * @after_tab: true if num_chars starts after a previous tab
* @tty: terminal device * @ldata: n_tty data
* *
* Add an operation to the echo buffer to erase a tab. * Add an operation to the echo buffer to erase a tab.
* *
@ -805,14 +793,12 @@ static void echo_set_canon_col(struct tty_struct *tty)
*/ */
static void echo_erase_tab(unsigned int num_chars, int after_tab, static void echo_erase_tab(unsigned int num_chars, int after_tab,
struct tty_struct *tty) struct n_tty_data *ldata)
{ {
struct n_tty_data *ldata = tty->disc_data;
mutex_lock(&ldata->echo_lock); mutex_lock(&ldata->echo_lock);
add_echo_byte(ECHO_OP_START, tty); add_echo_byte(ECHO_OP_START, ldata);
add_echo_byte(ECHO_OP_ERASE_TAB, tty); add_echo_byte(ECHO_OP_ERASE_TAB, ldata);
/* We only need to know this modulo 8 (tab spacing) */ /* We only need to know this modulo 8 (tab spacing) */
num_chars &= 7; num_chars &= 7;
@ -821,7 +807,7 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab,
if (after_tab) if (after_tab)
num_chars |= 0x80; num_chars |= 0x80;
add_echo_byte(num_chars, tty); add_echo_byte(num_chars, ldata);
mutex_unlock(&ldata->echo_lock); mutex_unlock(&ldata->echo_lock);
} }
@ -839,19 +825,15 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab,
* Locking: echo_lock to protect the echo buffer * Locking: echo_lock to protect the echo buffer
*/ */
static void echo_char_raw(unsigned char c, struct tty_struct *tty) static void echo_char_raw(unsigned char c, struct n_tty_data *ldata)
{ {
struct n_tty_data *ldata = tty->disc_data;
mutex_lock(&ldata->echo_lock); mutex_lock(&ldata->echo_lock);
if (c == ECHO_OP_START) { if (c == ECHO_OP_START) {
add_echo_byte(ECHO_OP_START, tty); add_echo_byte(ECHO_OP_START, ldata);
add_echo_byte(ECHO_OP_START, tty); add_echo_byte(ECHO_OP_START, ldata);
} else { } else {
add_echo_byte(c, tty); add_echo_byte(c, ldata);
} }
mutex_unlock(&ldata->echo_lock); mutex_unlock(&ldata->echo_lock);
} }
@ -876,12 +858,12 @@ static void echo_char(unsigned char c, struct tty_struct *tty)
mutex_lock(&ldata->echo_lock); mutex_lock(&ldata->echo_lock);
if (c == ECHO_OP_START) { if (c == ECHO_OP_START) {
add_echo_byte(ECHO_OP_START, tty); add_echo_byte(ECHO_OP_START, ldata);
add_echo_byte(ECHO_OP_START, tty); add_echo_byte(ECHO_OP_START, ldata);
} else { } else {
if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t')
add_echo_byte(ECHO_OP_START, tty); add_echo_byte(ECHO_OP_START, ldata);
add_echo_byte(c, tty); add_echo_byte(c, ldata);
} }
mutex_unlock(&ldata->echo_lock); mutex_unlock(&ldata->echo_lock);
@ -889,14 +871,13 @@ static void echo_char(unsigned char c, struct tty_struct *tty)
/** /**
* finish_erasing - complete erase * finish_erasing - complete erase
* @tty: tty doing the erase * @ldata: n_tty data
*/ */
static inline void finish_erasing(struct tty_struct *tty) static inline void finish_erasing(struct n_tty_data *ldata)
{ {
struct n_tty_data *ldata = tty->disc_data;
if (ldata->erasing) { if (ldata->erasing) {
echo_char_raw('/', tty); echo_char_raw('/', ldata);
ldata->erasing = 0; ldata->erasing = 0;
} }
} }
@ -944,11 +925,11 @@ static void eraser(unsigned char c, struct tty_struct *tty)
(N_TTY_BUF_SIZE - 1)); (N_TTY_BUF_SIZE - 1));
ldata->read_head = ldata->canon_head; ldata->read_head = ldata->canon_head;
spin_unlock_irqrestore(&ldata->read_lock, flags); spin_unlock_irqrestore(&ldata->read_lock, flags);
finish_erasing(tty); finish_erasing(ldata);
echo_char(KILL_CHAR(tty), tty); echo_char(KILL_CHAR(tty), tty);
/* Add a newline if ECHOK is on and ECHOKE is off. */ /* Add a newline if ECHOK is on and ECHOKE is off. */
if (L_ECHOK(tty)) if (L_ECHOK(tty))
echo_char_raw('\n', tty); echo_char_raw('\n', ldata);
return; return;
} }
kill_type = KILL; kill_type = KILL;
@ -984,15 +965,16 @@ static void eraser(unsigned char c, struct tty_struct *tty)
if (L_ECHO(tty)) { if (L_ECHO(tty)) {
if (L_ECHOPRT(tty)) { if (L_ECHOPRT(tty)) {
if (!ldata->erasing) { if (!ldata->erasing) {
echo_char_raw('\\', tty); echo_char_raw('\\', ldata);
ldata->erasing = 1; ldata->erasing = 1;
} }
/* if cnt > 1, output a multi-byte character */ /* if cnt > 1, output a multi-byte character */
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(ldata->read_buf[head], tty); echo_char_raw(ldata->read_buf[head],
echo_move_back_col(tty); ldata);
echo_move_back_col(ldata);
} }
} else if (kill_type == ERASE && !L_ECHOE(tty)) { } else if (kill_type == ERASE && !L_ECHOE(tty)) {
echo_char(ERASE_CHAR(tty), tty); echo_char(ERASE_CHAR(tty), tty);
@ -1021,17 +1003,17 @@ static void eraser(unsigned char c, struct tty_struct *tty)
num_chars++; num_chars++;
} }
} }
echo_erase_tab(num_chars, after_tab, tty); echo_erase_tab(num_chars, after_tab, ldata);
} else { } else {
if (iscntrl(c) && L_ECHOCTL(tty)) { if (iscntrl(c) && L_ECHOCTL(tty)) {
echo_char_raw('\b', tty); echo_char_raw('\b', ldata);
echo_char_raw(' ', tty); echo_char_raw(' ', ldata);
echo_char_raw('\b', tty); echo_char_raw('\b', ldata);
} }
if (!iscntrl(c) || L_ECHOCTL(tty)) { if (!iscntrl(c) || L_ECHOCTL(tty)) {
echo_char_raw('\b', tty); echo_char_raw('\b', ldata);
echo_char_raw(' ', tty); echo_char_raw(' ', ldata);
echo_char_raw('\b', tty); echo_char_raw('\b', ldata);
} }
} }
} }
@ -1039,7 +1021,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
break; break;
} }
if (ldata->read_head == ldata->canon_head && L_ECHO(tty)) if (ldata->read_head == ldata->canon_head && L_ECHO(tty))
finish_erasing(tty); finish_erasing(ldata);
} }
/** /**
@ -1078,6 +1060,8 @@ static inline void isig(int sig, struct tty_struct *tty, int flush)
static inline void n_tty_receive_break(struct tty_struct *tty) static inline void n_tty_receive_break(struct tty_struct *tty)
{ {
struct n_tty_data *ldata = tty->disc_data;
if (I_IGNBRK(tty)) if (I_IGNBRK(tty))
return; return;
if (I_BRKINT(tty)) { if (I_BRKINT(tty)) {
@ -1085,10 +1069,10 @@ static inline void n_tty_receive_break(struct tty_struct *tty)
return; return;
} }
if (I_PARMRK(tty)) { if (I_PARMRK(tty)) {
put_tty_queue('\377', tty); put_tty_queue('\377', ldata);
put_tty_queue('\0', tty); put_tty_queue('\0', ldata);
} }
put_tty_queue('\0', tty); put_tty_queue('\0', ldata);
wake_up_interruptible(&tty->read_wait); wake_up_interruptible(&tty->read_wait);
} }
@ -1132,16 +1116,18 @@ static inline void n_tty_receive_overrun(struct tty_struct *tty)
static inline void n_tty_receive_parity_error(struct tty_struct *tty, static inline void n_tty_receive_parity_error(struct tty_struct *tty,
unsigned char c) unsigned char c)
{ {
struct n_tty_data *ldata = tty->disc_data;
if (I_IGNPAR(tty)) if (I_IGNPAR(tty))
return; return;
if (I_PARMRK(tty)) { if (I_PARMRK(tty)) {
put_tty_queue('\377', tty); put_tty_queue('\377', ldata);
put_tty_queue('\0', tty); put_tty_queue('\0', ldata);
put_tty_queue(c, tty); put_tty_queue(c, ldata);
} else if (I_INPCK(tty)) } else if (I_INPCK(tty))
put_tty_queue('\0', tty); put_tty_queue('\0', ldata);
else else
put_tty_queue(c, tty); put_tty_queue(c, ldata);
wake_up_interruptible(&tty->read_wait); wake_up_interruptible(&tty->read_wait);
} }
@ -1162,7 +1148,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
int parmrk; int parmrk;
if (ldata->raw) { if (ldata->raw) {
put_tty_queue(c, tty); put_tty_queue(c, ldata);
return; return;
} }
@ -1172,7 +1158,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
c = tolower(c); c = tolower(c);
if (L_EXTPROC(tty)) { if (L_EXTPROC(tty)) {
put_tty_queue(c, tty); put_tty_queue(c, ldata);
return; return;
} }
@ -1210,16 +1196,16 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
return; return;
} }
if (L_ECHO(tty)) { if (L_ECHO(tty)) {
finish_erasing(tty); finish_erasing(ldata);
/* Record the column of first canon char. */ /* Record the column of first canon char. */
if (ldata->canon_head == ldata->read_head) if (ldata->canon_head == ldata->read_head)
echo_set_canon_col(tty); echo_set_canon_col(ldata);
echo_char(c, tty); echo_char(c, tty);
process_echoes(tty); process_echoes(tty);
} }
if (parmrk) if (parmrk)
put_tty_queue(c, tty); put_tty_queue(c, ldata);
put_tty_queue(c, tty); put_tty_queue(c, ldata);
return; return;
} }
@ -1285,10 +1271,10 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) {
ldata->lnext = 1; ldata->lnext = 1;
if (L_ECHO(tty)) { if (L_ECHO(tty)) {
finish_erasing(tty); finish_erasing(ldata);
if (L_ECHOCTL(tty)) { if (L_ECHOCTL(tty)) {
echo_char_raw('^', tty); echo_char_raw('^', ldata);
echo_char_raw('\b', tty); echo_char_raw('\b', ldata);
process_echoes(tty); process_echoes(tty);
} }
} }
@ -1298,9 +1284,9 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
L_IEXTEN(tty)) { L_IEXTEN(tty)) {
unsigned long tail = ldata->canon_head; unsigned long tail = ldata->canon_head;
finish_erasing(tty); finish_erasing(ldata);
echo_char(c, tty); echo_char(c, tty);
echo_char_raw('\n', tty); echo_char_raw('\n', ldata);
while (tail != ldata->read_head) { while (tail != ldata->read_head) {
echo_char(ldata->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);
@ -1315,7 +1301,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
return; return;
} }
if (L_ECHO(tty) || L_ECHONL(tty)) { if (L_ECHO(tty) || L_ECHONL(tty)) {
echo_char_raw('\n', tty); echo_char_raw('\n', ldata);
process_echoes(tty); process_echoes(tty);
} }
goto handle_newline; goto handle_newline;
@ -1343,7 +1329,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 (ldata->canon_head == ldata->read_head) if (ldata->canon_head == ldata->read_head)
echo_set_canon_col(tty); echo_set_canon_col(ldata);
echo_char(c, tty); echo_char(c, tty);
process_echoes(tty); process_echoes(tty);
} }
@ -1352,12 +1338,12 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
* EOL_CHAR and EOL2_CHAR? * EOL_CHAR and EOL2_CHAR?
*/ */
if (parmrk) if (parmrk)
put_tty_queue(c, tty); put_tty_queue(c, ldata);
handle_newline: handle_newline:
spin_lock_irqsave(&ldata->read_lock, flags); spin_lock_irqsave(&ldata->read_lock, flags);
set_bit(ldata->read_head, ldata->read_flags); set_bit(ldata->read_head, ldata->read_flags);
put_tty_queue_nolock(c, tty); put_tty_queue_nolock(c, ldata);
ldata->canon_head = ldata->read_head; ldata->canon_head = ldata->read_head;
ldata->canon_data++; ldata->canon_data++;
spin_unlock_irqrestore(&ldata->read_lock, flags); spin_unlock_irqrestore(&ldata->read_lock, flags);
@ -1376,22 +1362,22 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
return; return;
} }
if (L_ECHO(tty)) { if (L_ECHO(tty)) {
finish_erasing(tty); finish_erasing(ldata);
if (c == '\n') if (c == '\n')
echo_char_raw('\n', tty); echo_char_raw('\n', ldata);
else { else {
/* Record the column of first canon char. */ /* Record the column of first canon char. */
if (ldata->canon_head == ldata->read_head) if (ldata->canon_head == ldata->read_head)
echo_set_canon_col(tty); echo_set_canon_col(ldata);
echo_char(c, tty); echo_char(c, tty);
} }
process_echoes(tty); process_echoes(tty);
} }
if (parmrk) if (parmrk)
put_tty_queue(c, tty); put_tty_queue(c, ldata);
put_tty_queue(c, tty); put_tty_queue(c, ldata);
} }
@ -2140,9 +2126,8 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
return mask; return mask;
} }
static unsigned long inq_canon(struct tty_struct *tty) static unsigned long inq_canon(struct n_tty_data *ldata)
{ {
struct n_tty_data *ldata = tty->disc_data;
int nr, head, tail; int nr, head, tail;
if (!ldata->canon_data) if (!ldata->canon_data)
@ -2173,7 +2158,7 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
/* FIXME: Locking */ /* FIXME: Locking */
retval = ldata->read_cnt; retval = ldata->read_cnt;
if (L_ICANON(tty)) if (L_ICANON(tty))
retval = inq_canon(tty); retval = inq_canon(ldata);
return put_user(retval, (unsigned int __user *) arg); return put_user(retval, (unsigned int __user *) arg);
default: default:
return n_tty_ioctl_helper(tty, file, cmd, arg); return n_tty_ioctl_helper(tty, file, cmd, arg);