]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/um/drivers/chan_kern.c
uml: move userspace code to userspace file
[karo-tx-linux.git] / arch / um / drivers / chan_kern.c
index 3aa351611763cbcf625f5cc6a09b4f4aad41ea5f..9a6222f1a51b8a95c63384710c7fe6f3e538f872 100644 (file)
@@ -89,54 +89,6 @@ static const struct chan_ops not_configged_ops = {
 };
 #endif /* CONFIG_NOCONFIG_CHAN */
 
-void generic_close(int fd, void *unused)
-{
-       os_close_file(fd);
-}
-
-int generic_read(int fd, char *c_out, void *unused)
-{
-       int n;
-
-       n = os_read_file(fd, c_out, sizeof(*c_out));
-
-       if(n == -EAGAIN)
-               return 0;
-       else if(n == 0)
-               return -EIO;
-       return n;
-}
-
-/* XXX Trivial wrapper around os_write_file */
-
-int generic_write(int fd, const char *buf, int n, void *unused)
-{
-       return os_write_file(fd, buf, n);
-}
-
-int generic_window_size(int fd, void *unused, unsigned short *rows_out,
-                       unsigned short *cols_out)
-{
-       int rows, cols;
-       int ret;
-
-       ret = os_window_size(fd, &rows, &cols);
-       if(ret < 0)
-               return ret;
-
-       ret = ((*rows_out != rows) || (*cols_out != cols));
-
-       *rows_out = rows;
-       *cols_out = cols;
-
-       return ret;
-}
-
-void generic_free(void *data)
-{
-       kfree(data);
-}
-
 static void tty_receive_char(struct tty_struct *tty, char ch)
 {
        if(tty == NULL) return;
@@ -157,7 +109,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 +120,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 +162,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