um: switch users of ->chan_list to ->chan_{in,out} (easy cases)

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
Al Viro 2011-09-08 10:49:34 -04:00 committed by Richard Weinberger
parent ee4850702b
commit bed5e39c56
5 changed files with 87 additions and 127 deletions

View File

@ -27,24 +27,24 @@ struct chan {
void *data; void *data;
}; };
extern void chan_interrupt(struct list_head *chans, struct delayed_work *task, extern void chan_interrupt(struct line *line, struct delayed_work *task,
struct tty_struct *tty, int irq); struct tty_struct *tty, int irq);
extern int parse_chan_pair(char *str, struct line *line, int device, extern int parse_chan_pair(char *str, struct line *line, int device,
const struct chan_opts *opts, char **error_out); const struct chan_opts *opts, char **error_out);
extern int write_chan(struct list_head *chans, const char *buf, int len, extern int write_chan(struct chan *chan, const char *buf, int len,
int write_irq); int write_irq);
extern int console_write_chan(struct list_head *chans, const char *buf, extern int console_write_chan(struct chan *chan, const char *buf,
int len); int len);
extern int console_open_chan(struct line *line, struct console *co); extern int console_open_chan(struct line *line, struct console *co);
extern void deactivate_chan(struct list_head *chans, int irq); extern void deactivate_chan(struct chan *chan, int irq);
extern void reactivate_chan(struct list_head *chans, int irq); extern void reactivate_chan(struct chan *chan, int irq);
extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); extern void chan_enable_winch(struct chan *chan, struct tty_struct *tty);
extern int enable_chan(struct line *line); extern int enable_chan(struct line *line);
extern void close_chan(struct list_head *chans, int delay_free_irq); extern void close_chan(struct list_head *chans, int delay_free_irq);
extern int chan_window_size(struct list_head *chans, extern int chan_window_size(struct line *line,
unsigned short *rows_out, unsigned short *rows_out,
unsigned short *cols_out); unsigned short *cols_out);
extern int chan_config_string(struct list_head *chans, char *str, int size, extern int chan_config_string(struct line *line, char *str, int size,
char **error_out); char **error_out);
#endif #endif

View File

@ -140,18 +140,10 @@ static int open_chan(struct list_head *chans)
return err; return err;
} }
void chan_enable_winch(struct list_head *chans, struct tty_struct *tty) void chan_enable_winch(struct chan *chan, struct tty_struct *tty)
{ {
struct list_head *ele; if (chan && chan->primary && chan->ops->winch)
struct chan *chan; register_winch(chan->fd, tty);
list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
if (chan->primary && chan->output && chan->ops->winch) {
register_winch(chan->fd, tty);
return;
}
}
} }
int enable_chan(struct line *line) int enable_chan(struct line *line)
@ -258,72 +250,45 @@ void close_chan(struct list_head *chans, int delay_free_irq)
} }
} }
void deactivate_chan(struct list_head *chans, int irq) void deactivate_chan(struct chan *chan, int irq)
{ {
struct list_head *ele; if (chan && chan->enabled)
deactivate_fd(chan->fd, irq);
struct chan *chan;
list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
if (chan->enabled && chan->input)
deactivate_fd(chan->fd, irq);
}
} }
void reactivate_chan(struct list_head *chans, int irq) void reactivate_chan(struct chan *chan, int irq)
{ {
struct list_head *ele; if (chan && chan->enabled)
struct chan *chan; reactivate_fd(chan->fd, irq);
list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
if (chan->enabled && chan->input)
reactivate_fd(chan->fd, irq);
}
} }
int write_chan(struct list_head *chans, const char *buf, int len, int write_chan(struct chan *chan, const char *buf, int len,
int write_irq) int write_irq)
{ {
struct list_head *ele;
struct chan *chan = NULL;
int n, ret = 0; int n, ret = 0;
if (len == 0) if (len == 0 || !chan || !chan->ops->write)
return 0; return 0;
list_for_each(ele, chans) { n = chan->ops->write(chan->fd, buf, len, chan->data);
chan = list_entry(ele, struct chan, list); if (chan->primary) {
if (!chan->output || (chan->ops->write == NULL)) ret = n;
continue; if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len)))
reactivate_fd(chan->fd, write_irq);
n = chan->ops->write(chan->fd, buf, len, chan->data);
if (chan->primary) {
ret = n;
if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len)))
reactivate_fd(chan->fd, write_irq);
}
} }
return ret; return ret;
} }
int console_write_chan(struct list_head *chans, const char *buf, int len) int console_write_chan(struct chan *chan, const char *buf, int len)
{ {
struct list_head *ele;
struct chan *chan;
int n, ret = 0; int n, ret = 0;
list_for_each(ele, chans) { if (!chan || !chan->ops->console_write)
chan = list_entry(ele, struct chan, list); return 0;
if (!chan->output || (chan->ops->console_write == NULL))
continue;
n = chan->ops->console_write(chan->fd, buf, len); n = chan->ops->console_write(chan->fd, buf, len);
if (chan->primary) if (chan->primary)
ret = n; ret = n;
}
return ret; return ret;
} }
@ -340,20 +305,24 @@ int console_open_chan(struct line *line, struct console *co)
return 0; return 0;
} }
int chan_window_size(struct list_head *chans, unsigned short *rows_out, int chan_window_size(struct line *line, unsigned short *rows_out,
unsigned short *cols_out) unsigned short *cols_out)
{ {
struct list_head *ele;
struct chan *chan; struct chan *chan;
list_for_each(ele, chans) { chan = line->chan_in;
chan = list_entry(ele, struct chan, list); if (chan && chan->primary) {
if (chan->primary) { if (chan->ops->window_size == NULL)
if (chan->ops->window_size == NULL) return 0;
return 0; return chan->ops->window_size(chan->fd, chan->data,
return chan->ops->window_size(chan->fd, chan->data, rows_out, cols_out);
rows_out, cols_out); }
} chan = line->chan_out;
if (chan && chan->primary) {
if (chan->ops->window_size == NULL)
return 0;
return chan->ops->window_size(chan->fd, chan->data,
rows_out, cols_out);
} }
return 0; return 0;
} }
@ -429,21 +398,15 @@ static int chan_pair_config_string(struct chan *in, struct chan *out,
return n; return n;
} }
int chan_config_string(struct list_head *chans, char *str, int size, int chan_config_string(struct line *line, char *str, int size,
char **error_out) char **error_out)
{ {
struct list_head *ele; struct chan *in = line->chan_in, *out = line->chan_out;
struct chan *chan, *in = NULL, *out = NULL;
list_for_each(ele, chans) { if (in && !in->primary)
chan = list_entry(ele, struct chan, list); in = NULL;
if (!chan->primary) if (out && !out->primary)
continue; out = NULL;
if (chan->input)
in = chan;
if (chan->output)
out = chan;
}
return chan_pair_config_string(in, out, str, size, error_out); return chan_pair_config_string(in, out, str, size, error_out);
} }
@ -589,39 +552,36 @@ int parse_chan_pair(char *str, struct line *line, int device,
return 0; return 0;
} }
void chan_interrupt(struct list_head *chans, struct delayed_work *task, void chan_interrupt(struct line *line, struct delayed_work *task,
struct tty_struct *tty, int irq) struct tty_struct *tty, int irq)
{ {
struct list_head *ele, *next; struct chan *chan = line->chan_in;
struct chan *chan;
int err; int err;
char c; char c;
list_for_each_safe(ele, next, chans) { if (!chan || !chan->ops->read)
chan = list_entry(ele, struct chan, list); goto out;
if (!chan->input || (chan->ops->read == NULL))
continue;
do {
if (tty && !tty_buffer_request_room(tty, 1)) {
schedule_delayed_work(task, 1);
goto out;
}
err = chan->ops->read(chan->fd, &c, chan->data);
if (err > 0)
tty_receive_char(tty, c);
} while (err > 0);
if (err == 0) do {
reactivate_fd(chan->fd, irq); if (tty && !tty_buffer_request_room(tty, 1)) {
if (err == -EIO) { schedule_delayed_work(task, 1);
if (chan->primary) { goto out;
if (tty != NULL)
tty_hangup(tty);
close_chan(chans, 1);
return;
}
else close_one_chan(chan, 1);
} }
err = chan->ops->read(chan->fd, &c, chan->data);
if (err > 0)
tty_receive_char(tty, c);
} while (err > 0);
if (err == 0)
reactivate_fd(chan->fd, irq);
if (err == -EIO) {
if (chan->primary) {
if (tty != NULL)
tty_hangup(tty);
close_chan(&line->chan_list, 1);
return;
}
else close_one_chan(chan, 1);
} }
out: out:
if (tty) if (tty)

View File

@ -21,7 +21,7 @@ static irqreturn_t line_interrupt(int irq, void *data)
struct line *line = chan->line; struct line *line = chan->line;
if (line) if (line)
chan_interrupt(&line->chan_list, &line->task, line->tty, irq); chan_interrupt(line, &line->task, line->tty, irq);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -30,7 +30,7 @@ static void line_timer_cb(struct work_struct *work)
struct line *line = container_of(work, struct line, task.work); struct line *line = container_of(work, struct line, task.work);
if (!line->throttled) if (!line->throttled)
chan_interrupt(&line->chan_list, &line->task, line->tty, chan_interrupt(line, &line->task, line->tty,
line->driver->read_irq); line->driver->read_irq);
} }
@ -145,7 +145,7 @@ static int flush_buffer(struct line *line)
/* line->buffer + LINE_BUFSIZE is the end of the buffer! */ /* line->buffer + LINE_BUFSIZE is the end of the buffer! */
count = line->buffer + LINE_BUFSIZE - line->head; count = line->buffer + LINE_BUFSIZE - line->head;
n = write_chan(&line->chan_list, line->head, count, n = write_chan(line->chan_out, line->head, count,
line->driver->write_irq); line->driver->write_irq);
if (n < 0) if (n < 0)
return n; return n;
@ -162,7 +162,7 @@ static int flush_buffer(struct line *line)
} }
count = line->tail - line->head; count = line->tail - line->head;
n = write_chan(&line->chan_list, line->head, count, n = write_chan(line->chan_out, line->head, count,
line->driver->write_irq); line->driver->write_irq);
if (n < 0) if (n < 0)
@ -206,7 +206,7 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
if (line->head != line->tail) if (line->head != line->tail)
ret = buffer_data(line, buf, len); ret = buffer_data(line, buf, len);
else { else {
n = write_chan(&line->chan_list, buf, len, n = write_chan(line->chan_out, buf, len,
line->driver->write_irq); line->driver->write_irq);
if (n < 0) { if (n < 0) {
ret = n; ret = n;
@ -318,7 +318,7 @@ void line_throttle(struct tty_struct *tty)
{ {
struct line *line = tty->driver_data; struct line *line = tty->driver_data;
deactivate_chan(&line->chan_list, line->driver->read_irq); deactivate_chan(line->chan_in, line->driver->read_irq);
line->throttled = 1; line->throttled = 1;
} }
@ -327,7 +327,7 @@ void line_unthrottle(struct tty_struct *tty)
struct line *line = tty->driver_data; struct line *line = tty->driver_data;
line->throttled = 0; line->throttled = 0;
chan_interrupt(&line->chan_list, &line->task, tty, chan_interrupt(line, &line->task, tty,
line->driver->read_irq); line->driver->read_irq);
/* /*
@ -336,7 +336,7 @@ void line_unthrottle(struct tty_struct *tty)
* again and we shouldn't turn the interrupt back on. * again and we shouldn't turn the interrupt back on.
*/ */
if (!line->throttled) if (!line->throttled)
reactivate_chan(&line->chan_list, line->driver->read_irq); reactivate_chan(line->chan_in, line->driver->read_irq);
} }
static irqreturn_t line_write_interrupt(int irq, void *data) static irqreturn_t line_write_interrupt(int irq, void *data)
@ -428,11 +428,11 @@ int line_open(struct line *lines, struct tty_struct *tty)
INIT_DELAYED_WORK(&line->task, line_timer_cb); INIT_DELAYED_WORK(&line->task, line_timer_cb);
if (!line->sigio) { if (!line->sigio) {
chan_enable_winch(&line->chan_list, tty); chan_enable_winch(line->chan_out, tty);
line->sigio = 1; line->sigio = 1;
} }
chan_window_size(&line->chan_list, &tty->winsize.ws_row, chan_window_size(line, &tty->winsize.ws_row,
&tty->winsize.ws_col); &tty->winsize.ws_col);
out_unlock: out_unlock:
mutex_unlock(&line->count_lock); mutex_unlock(&line->count_lock);
@ -624,7 +624,7 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
CONFIG_CHUNK(str, size, n, "none", 1); CONFIG_CHUNK(str, size, n, "none", 1);
else if (line->tty == NULL) else if (line->tty == NULL)
CONFIG_CHUNK(str, size, n, line->init_str, 1); CONFIG_CHUNK(str, size, n, line->init_str, 1);
else n = chan_config_string(&line->chan_list, str, size, error_out); else n = chan_config_string(line, str, size, error_out);
mutex_unlock(&line->count_lock); mutex_unlock(&line->count_lock);
return n; return n;
@ -761,7 +761,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
if (tty != NULL) { if (tty != NULL) {
line = tty->driver_data; line = tty->driver_data;
if (line != NULL) { if (line != NULL) {
chan_window_size(&line->chan_list, &tty->winsize.ws_row, chan_window_size(line, &tty->winsize.ws_row,
&tty->winsize.ws_col); &tty->winsize.ws_col);
kill_pgrp(tty->pgrp, SIGWINCH, 1); kill_pgrp(tty->pgrp, SIGWINCH, 1);
} }

View File

@ -151,7 +151,7 @@ static void ssl_console_write(struct console *c, const char *string,
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&line->lock, flags); spin_lock_irqsave(&line->lock, flags);
console_write_chan(&line->chan_list, string, len); console_write_chan(line->chan_out, string, len);
spin_unlock_irqrestore(&line->lock, flags); spin_unlock_irqrestore(&line->lock, flags);
} }

View File

@ -124,7 +124,7 @@ static void uml_console_write(struct console *console, const char *string,
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&line->lock, flags); spin_lock_irqsave(&line->lock, flags);
console_write_chan(&line->chan_list, string, len); console_write_chan(line->chan_out, string, len);
spin_unlock_irqrestore(&line->lock, flags); spin_unlock_irqrestore(&line->lock, flags);
} }