diff options
Diffstat (limited to 'arch/um/drivers/chan_kern.c')
-rw-r--r-- | arch/um/drivers/chan_kern.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 3aa351611763..629b00e3b0b0 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -157,7 +157,7 @@ static void tty_receive_char(struct tty_struct *tty, char ch) static int open_one_chan(struct chan *chan) { - int fd; + int fd, err; if(chan->opened) return 0; @@ -168,6 +168,13 @@ static int open_one_chan(struct chan *chan) chan->data, &chan->dev); if(fd < 0) return fd; + + err = os_set_fd_block(fd, 0); + if (err) { + (*chan->ops->close)(fd, chan->data); + return err; + } + chan->fd = fd; chan->opened = 1; @@ -203,22 +210,37 @@ void chan_enable_winch(struct list_head *chans, struct tty_struct *tty) } } -void enable_chan(struct line *line) +int enable_chan(struct line *line) { struct list_head *ele; struct chan *chan; + int err; list_for_each(ele, &line->chan_list){ chan = list_entry(ele, struct chan, list); - if(open_one_chan(chan)) + err = open_one_chan(chan); + if (err) { + if (chan->primary) + goto out_close; + continue; + } if(chan->enabled) continue; - line_setup_irq(chan->fd, chan->input, chan->output, line, - chan); + err = line_setup_irq(chan->fd, chan->input, chan->output, line, + chan); + if (err) + goto out_close; + chan->enabled = 1; } + + return 0; + + out_close: + close_chan(&line->chan_list, 0); + return err; } /* Items are added in IRQ context, when free_irq can't be called, and |