]> err.no Git - linux-2.6/blobdiff - arch/um/drivers/chan_kern.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
[linux-2.6] / arch / um / drivers / chan_kern.c
index 9fdfad649536fbac0c676f84cf46d2bc928485a9..629b00e3b0b0c36f39800836d8525afd14456999 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/tty_flip.h>
 #include <asm/irq.h>
 #include "chan_kern.h"
-#include "user_util.h"
 #include "kern.h"
 #include "irq_user.h"
 #include "sigio.h"
@@ -158,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;
@@ -169,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;
@@ -204,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