6 #include <linux/slab.h>
13 #ifdef CONFIG_NOCONFIG_CHAN
14 static void *not_configged_init(
char *
str,
int device,
22 static int not_configged_open(
int input,
int output,
int primary,
void *
data,
30 static void not_configged_close(
int fd,
void *
data)
36 static int not_configged_read(
int fd,
char *c_out,
void *
data)
43 static int not_configged_write(
int fd,
const char *
buf,
int len,
void *
data)
50 static int not_configged_console_write(
int fd,
const char *
buf,
int len)
57 static int not_configged_window_size(
int fd,
void *
data,
unsigned short *
rows,
65 static void not_configged_free(
void *
data)
71 static const struct chan_ops not_configged_ops = {
72 .
init = not_configged_init,
73 .open = not_configged_open,
74 .close = not_configged_close,
75 .read = not_configged_read,
76 .write = not_configged_write,
77 .console_write = not_configged_console_write,
78 .window_size = not_configged_window_size,
79 .free = not_configged_free,
84 static void tty_receive_char(
struct tty_struct *tty,
char ch)
103 static int open_one_chan(
struct chan *
chan)
119 (*chan->
ops->close)(fd, chan->
data);
129 static int open_chan(
struct list_head *chans)
137 ret = open_one_chan(chan);
146 if (chan && chan->
primary && chan->
ops->winch)
170 err = open_one_chan(chan);
212 list_splice_init(&irqs_to_free, &
list);
213 spin_unlock_irqrestore(&irqs_to_free_lock, flags);
226 static void close_one_chan(
struct chan *chan,
int delay_free_irq)
233 if (delay_free_irq) {
235 list_add(&chan->
free_list, &irqs_to_free);
236 spin_unlock_irqrestore(&irqs_to_free_lock, flags);
246 (*chan->
ops->close)(chan->
fd, chan->
data);
262 close_one_chan(chan, 0);
283 if (len == 0 || !chan || !chan->
ops->write)
286 n = chan->
ops->write(chan->
fd, buf, len, chan->
data);
289 if ((ret == -
EAGAIN) || ((ret >= 0) && (ret < len)))
299 if (!chan || !chan->
ops->console_write)
302 n = chan->
ops->console_write(chan->
fd, buf, len);
322 unsigned short *cols_out)
328 if (chan->
ops->window_size ==
NULL)
330 return chan->
ops->window_size(chan->
fd, chan->
data,
335 if (chan->
ops->window_size ==
NULL)
337 return chan->
ops->window_size(chan->
fd, chan->
data,
343 static void free_one_chan(
struct chan *chan)
347 close_one_chan(chan, 0);
350 (*chan->
ops->free)(chan->
data);
357 static void free_chan(
struct list_head *chans)
368 static int one_chan_config_string(
struct chan *chan,
char *
str,
int size,
391 static int chan_pair_config_string(
struct chan *
in,
struct chan *
out,
392 char *str,
int size,
char **error_out)
396 n = one_chan_config_string(in, str, size, error_out);
406 n = one_chan_config_string(out, str, size, error_out);
424 return chan_pair_config_string(in, out, str, size, error_out);
432 static const struct chan_type chan_table[] = {
435 #ifdef CONFIG_NULL_CHAN
438 {
"null", ¬_configged_ops },
441 #ifdef CONFIG_PORT_CHAN
444 {
"port", ¬_configged_ops },
447 #ifdef CONFIG_PTY_CHAN
451 {
"pty", ¬_configged_ops },
452 {
"pts", ¬_configged_ops },
455 #ifdef CONFIG_TTY_CHAN
458 {
"tty", ¬_configged_ops },
461 #ifdef CONFIG_XTERM_CHAN
464 {
"xterm", ¬_configged_ops },
468 static struct chan *parse_chan(
struct line *line,
char *str,
int device,
480 entry = &chan_table[
i];
488 *error_out =
"No match for configured backends";
492 data = (*ops->
init)(str, device, opts);
494 *error_out =
"Configuration failed";
500 *error_out =
"Memory allocation failed";
519 const struct chan_opts *opts,
char **error_out)
525 if (!list_empty(chans)) {
528 INIT_LIST_HEAD(chans);
539 new = parse_chan(line, in, device, opts, error_out);
544 list_add(&new->list, chans);
547 new = parse_chan(line, out, device, opts, error_out);
551 list_add(&new->list, chans);
556 new = parse_chan(line, str, device, opts, error_out);
560 list_add(&new->list, chans);
570 struct chan *chan = line->
chan_in;
574 if (!chan || !chan->
ops->read)
582 err = chan->
ops->read(chan->
fd, &c, chan->
data);
584 tty_receive_char(tty, c);
596 close_one_chan(chan, 1);