This patch adds support for throttling and unthrottling input when
the tty driver can't handle it.

Index: linux-2.6.15/arch/um/drivers/ssl.c
===================================================================
--- linux-2.6.15.orig/arch/um/drivers/ssl.c     2006-01-03 17:32:45.000000000 
-0500
+++ linux-2.6.15/arch/um/drivers/ssl.c  2006-01-03 17:35:00.000000000 -0500
@@ -109,16 +109,6 @@ static void ssl_flush_buffer(struct tty_
        return;
 }
 
-static void ssl_throttle(struct tty_struct * tty)
-{
-       printk(KERN_ERR "Someone should implement ssl_throttle\n");
-}
-
-static void ssl_unthrottle(struct tty_struct * tty)
-{
-       printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
-}
-
 static void ssl_stop(struct tty_struct *tty)
 {
        printk(KERN_ERR "Someone should implement ssl_stop\n");
@@ -145,9 +135,9 @@ static struct tty_operations ssl_ops = {
        .flush_chars            = line_flush_chars,
        .set_termios            = line_set_termios,
        .ioctl                  = line_ioctl,
+       .throttle               = line_throttle,
+       .unthrottle             = line_unthrottle,
 #if 0
-       .throttle               = ssl_throttle,
-       .unthrottle             = ssl_unthrottle,
        .stop                   = ssl_stop,
        .start                  = ssl_start,
        .hangup                 = ssl_hangup,
Index: linux-2.6.15/arch/um/drivers/stdio_console.c
===================================================================
--- linux-2.6.15.orig/arch/um/drivers/stdio_console.c   2006-01-03 
17:32:45.000000000 -0500
+++ linux-2.6.15/arch/um/drivers/stdio_console.c        2006-01-03 
17:35:00.000000000 -0500
@@ -122,6 +122,8 @@ static struct tty_operations console_ops
        .flush_chars            = line_flush_chars,
        .set_termios            = line_set_termios,
        .ioctl                  = line_ioctl,
+       .throttle               = line_throttle,
+       .unthrottle             = line_unthrottle,
 };
 
 static void uml_console_write(struct console *console, const char *string,
Index: linux-2.6.15/arch/um/include/line.h
===================================================================
--- linux-2.6.15.orig/arch/um/include/line.h    2006-01-03 17:33:23.000000000 
-0500
+++ linux-2.6.15/arch/um/include/line.h 2006-01-03 17:35:00.000000000 -0500
@@ -38,6 +38,7 @@ struct line {
        struct list_head chan_list;
        int valid;
        int count;
+       int throttled;
        /*This lock is actually, mostly, local to*/
        spinlock_t lock;
 
@@ -60,6 +61,7 @@ struct line {
        { init_str :    str, \
          init_pri :    INIT_STATIC, \
          valid :       1, \
+         throttled :   0, \
          lock :        SPIN_LOCK_UNLOCKED, \
          buffer :      NULL, \
          head :        NULL, \
@@ -88,6 +90,8 @@ extern void line_flush_chars(struct tty_
 extern int line_write_room(struct tty_struct *tty);
 extern int line_ioctl(struct tty_struct *tty, struct file * file,
                      unsigned int cmd, unsigned long arg);
+extern void line_throttle(struct tty_struct *tty);
+extern void line_unthrottle(struct tty_struct *tty);
 
 extern char *add_xterm_umid(char *base);
 extern int line_setup_irq(int fd, int input, int output, struct line *line,
Index: linux-2.6.15/arch/um/drivers/line.c
===================================================================
--- linux-2.6.15.orig/arch/um/drivers/line.c    2006-01-03 17:33:23.000000000 
-0500
+++ linux-2.6.15/arch/um/drivers/line.c 2006-01-03 17:35:00.000000000 -0500
@@ -36,8 +36,9 @@ static void line_timer_cb(void *arg)
 {
        struct line *line = arg;
 
-       chan_interrupt(&line->chan_list, &line->task, line->tty,
-                      line->driver->read_irq);
+       if(!line->throttled)
+               chan_interrupt(&line->chan_list, &line->task, line->tty,
+                              line->driver->read_irq);
 }
 
 /* Returns the free space inside the ring buffer of this line.
@@ -340,6 +341,30 @@ int line_ioctl(struct tty_struct *tty, s
        return ret;
 }
 
+void line_throttle(struct tty_struct *tty)
+{
+       struct line *line = tty->driver_data;
+
+       deactivate_chan(&line->chan_list, line->driver->read_irq);
+       line->throttled = 1;
+}
+
+void line_unthrottle(struct tty_struct *tty)
+{
+       struct line *line = tty->driver_data;
+
+       line->throttled = 0;
+       chan_interrupt(&line->chan_list, &line->task, tty,
+                      line->driver->read_irq);
+
+       /* Maybe there is enough stuff pending that calling the interrupt
+        * throttles us again.  In this case, line->throttled will be 1
+        * again and we shouldn't turn the interrupt back on.
+        */
+       if(!line->throttled)
+               reactivate_chan(&line->chan_list, line->driver->read_irq);
+}
+
 static irqreturn_t line_write_interrupt(int irq, void *data,
                                        struct pt_regs *unused)
 {
Index: linux-2.6.15/arch/um/drivers/chan_kern.c
===================================================================
--- linux-2.6.15.orig/arch/um/drivers/chan_kern.c       2006-01-03 
17:34:49.000000000 -0500
+++ linux-2.6.15/arch/um/drivers/chan_kern.c    2006-01-03 17:35:00.000000000 
-0500
@@ -312,6 +312,32 @@ void close_chan(struct list_head *chans,
        }
 }
 
+void deactivate_chan(struct list_head *chans, int irq)
+{
+       struct list_head *ele;
+
+       struct chan *chan;
+       list_for_each(ele, chans) {
+               chan = list_entry(ele, struct chan, list);
+
+               if(chan->enabled && chan->input)
+                       deactivate_fd(chan->fd, irq);
+       }
+}
+
+void reactivate_chan(struct list_head *chans, int irq)
+{
+       struct list_head *ele;
+       struct chan *chan;
+
+       list_for_each(ele, chans) {
+               chan = list_entry(ele, struct chan, list);
+
+               if(chan->enabled && chan->input)
+                       reactivate_fd(chan->fd, irq);
+       }
+}
+
 int write_chan(struct list_head *chans, const char *buf, int len,
               int write_irq)
 {
Index: linux-2.6.15/arch/um/include/chan_kern.h
===================================================================
--- linux-2.6.15.orig/arch/um/include/chan_kern.h       2006-01-03 
17:33:23.000000000 -0500
+++ linux-2.6.15/arch/um/include/chan_kern.h    2006-01-03 17:35:00.000000000 
-0500
@@ -38,6 +38,8 @@ extern int console_write_chan(struct lis
                              int len);
 extern int console_open_chan(struct line *line, struct console *co,
                             struct chan_opts *opts);
+extern void deactivate_chan(struct list_head *chans, int irq);
+extern void reactivate_chan(struct list_head *chans, int irq);
 extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty);
 extern void enable_chan(struct line *line);
 extern void close_chan(struct list_head *chans, int delay_free_irq);



-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

Reply via email to