vserver 1.9.5.x5
[linux-2.6.git] / arch / um / drivers / chan_kern.c
index 9e45a08..f30ae1b 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/tty.h>
+#include <linux/string.h>
 #include <linux/tty_flip.h>
 #include <asm/irq.h>
 #include "chan_kern.h"
@@ -16,7 +17,9 @@
 #include "irq_user.h"
 #include "sigio.h"
 #include "line.h"
+#include "os.h"
 
+#ifdef CONFIG_NOCONFIG_CHAN
 static void *not_configged_init(char *str, int device, struct chan_opts *opts)
 {
        printk(KERN_ERR "Using a channel type which is configured out of "
@@ -85,6 +88,55 @@ static struct chan_ops not_configged_ops = {
        .free           = not_configged_free,
        .winch          = 0,
 };
+#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)
 {
@@ -137,7 +189,7 @@ int open_chan(struct list_head *chans)
        return(err);
 }
 
-void chan_enable_winch(struct list_head *chans, void *line)
+void chan_enable_winch(struct list_head *chans, struct tty_struct *tty)
 {
        struct list_head *ele;
        struct chan *chan;
@@ -145,13 +197,13 @@ void chan_enable_winch(struct list_head *chans, void *line)
        list_for_each(ele, chans){
                chan = list_entry(ele, struct chan, list);
                if(chan->primary && chan->output && chan->ops->winch){
-                       register_winch(chan->fd, line);
+                       register_winch(chan->fd, tty);
                        return;
                }
        }
 }
 
-void enable_chan(struct list_head *chans, void *data)
+void enable_chan(struct list_head *chans, struct tty_struct *tty)
 {
        struct list_head *ele;
        struct chan *chan;
@@ -160,7 +212,7 @@ void enable_chan(struct list_head *chans, void *data)
                chan = list_entry(ele, struct chan, list);
                if(!chan->opened) continue;
 
-               line_setup_irq(chan->fd, chan->input, chan->output, data);
+               line_setup_irq(chan->fd, chan->input, chan->output, tty);
        }
 }
 
@@ -188,18 +240,20 @@ int write_chan(struct list_head *chans, const char *buf, int len,
               int write_irq)
 {
        struct list_head *ele;
-       struct chan *chan;
+       struct chan *chan = NULL;
        int n, ret = 0;
 
-       list_for_each(ele, chans){
+       list_for_each(ele, chans) {
                chan = list_entry(ele, struct chan, list);
-               if(!chan->output || (chan->ops->write == NULL)) continue;
+               if (!chan->output || (chan->ops->write == NULL))
+                       continue;
                n = chan->ops->write(chan->fd, buf, len, chan->data);
-               if(chan->primary){
+               if (chan->primary) {
                        ret = n;
-                       if((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
+                       if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
                                reactivate_fd(chan->fd, write_irq);
-                               if(ret == -EAGAIN) ret = 0;
+                               if (ret == -EAGAIN)
+                                       ret = 0;
                        }
                }
        }
@@ -222,6 +276,20 @@ int console_write_chan(struct list_head *chans, const char *buf, int len)
        return(ret);
 }
 
+int console_open_chan(struct line *line, struct console *co, struct chan_opts *opts)
+{
+       if (!list_empty(&line->chan_list))
+               return 0;
+
+       if (0 != parse_chan_pair(line->init_str, &line->chan_list,
+                                line->init_pri, co->index, opts))
+               return -1;
+       if (0 != open_chan(&line->chan_list))
+               return -1;
+       printk("Console initialized on /dev/%s%d\n",co->name,co->index);
+       return 0;
+}
+
 int chan_window_size(struct list_head *chans, unsigned short *rows_out,
                      unsigned short *cols_out)
 {
@@ -265,6 +333,11 @@ static int one_chan_config_string(struct chan *chan, char *str, int size,
 {
        int n = 0;
 
+       if(chan == NULL){
+               CONFIG_CHUNK(str, size, n, "none", 1);
+               return(n);
+       }
+
        CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
 
        if(chan->dev == NULL){
@@ -326,11 +399,7 @@ struct chan_type {
 };
 
 struct chan_type chan_table[] = {
-#ifdef CONFIG_FD_CHAN
        { "fd", &fd_ops },
-#else
-       { "fd", &not_configged_ops },
-#endif
 
 #ifdef CONFIG_NULL_CHAN
        { "null", &null_ops },
@@ -420,7 +489,8 @@ int parse_chan_pair(char *str, struct list_head *chans, int pri, int device,
                INIT_LIST_HEAD(chans);
        }
 
-       if((out = strchr(str, ',')) != NULL){
+       out = strchr(str, ',');
+       if(out != NULL){
                in = str;
                *out = '\0';
                out++;
@@ -458,7 +528,7 @@ int chan_out_fd(struct list_head *chans)
 }
 
 void chan_interrupt(struct list_head *chans, struct work_struct *task,
-                   struct tty_struct *tty, int irq, void *dev)
+                   struct tty_struct *tty, int irq)
 {
        struct list_head *ele, *next;
        struct chan *chan;
@@ -475,13 +545,16 @@ void chan_interrupt(struct list_head *chans, struct work_struct *task,
                                goto out;
                        }
                        err = chan->ops->read(chan->fd, &c, chan->data);
-                       if(err > 0) tty_receive_char(tty, c);
+                       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);
-                               line_disable(dev, irq);
+                               if(tty != NULL)
+                                       tty_hangup(tty);
+                               line_disable(tty, irq);
                                close_chan(chans);
                                free_chan(chans);
                                return;