aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2006-01-06 03:18:58 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:46 -0500
commite4dcee8099802c71437a15b940f66106d9f88b2f (patch)
treeb4831639d38369fce2e20fd40730425ca702102c
parent9159c9dfffe1746d58b015ceaa3b7b8e99ee9d5c (diff)
[PATCH] uml: Add throttling to console driver
This patch adds support for throttling and unthrottling input when the tty driver can't handle it. Signed-off-by: Jeff Dike <jdike@addtoit.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/um/drivers/chan_kern.c26
-rw-r--r--arch/um/drivers/line.c29
-rw-r--r--arch/um/drivers/ssl.c14
-rw-r--r--arch/um/drivers/stdio_console.c2
-rw-r--r--arch/um/include/chan_kern.h2
-rw-r--r--arch/um/include/line.h4
6 files changed, 63 insertions, 14 deletions
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 36df55ad64c2..cd13b91b9ff6 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -312,6 +312,32 @@ void close_chan(struct list_head *chans, int delay_free_irq)
312 } 312 }
313} 313}
314 314
315void deactivate_chan(struct list_head *chans, int irq)
316{
317 struct list_head *ele;
318
319 struct chan *chan;
320 list_for_each(ele, chans) {
321 chan = list_entry(ele, struct chan, list);
322
323 if(chan->enabled && chan->input)
324 deactivate_fd(chan->fd, irq);
325 }
326}
327
328void reactivate_chan(struct list_head *chans, int irq)
329{
330 struct list_head *ele;
331 struct chan *chan;
332
333 list_for_each(ele, chans) {
334 chan = list_entry(ele, struct chan, list);
335
336 if(chan->enabled && chan->input)
337 reactivate_fd(chan->fd, irq);
338 }
339}
340
315int write_chan(struct list_head *chans, const char *buf, int len, 341int write_chan(struct list_head *chans, const char *buf, int len,
316 int write_irq) 342 int write_irq)
317{ 343{
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 851a7c8caae5..b8e3e800ee41 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -36,8 +36,9 @@ static void line_timer_cb(void *arg)
36{ 36{
37 struct line *line = arg; 37 struct line *line = arg;
38 38
39 chan_interrupt(&line->chan_list, &line->task, line->tty, 39 if(!line->throttled)
40 line->driver->read_irq); 40 chan_interrupt(&line->chan_list, &line->task, line->tty,
41 line->driver->read_irq);
41} 42}
42 43
43/* Returns the free space inside the ring buffer of this line. 44/* Returns the free space inside the ring buffer of this line.
@@ -340,6 +341,30 @@ int line_ioctl(struct tty_struct *tty, struct file * file,
340 return ret; 341 return ret;
341} 342}
342 343
344void line_throttle(struct tty_struct *tty)
345{
346 struct line *line = tty->driver_data;
347
348 deactivate_chan(&line->chan_list, line->driver->read_irq);
349 line->throttled = 1;
350}
351
352void line_unthrottle(struct tty_struct *tty)
353{
354 struct line *line = tty->driver_data;
355
356 line->throttled = 0;
357 chan_interrupt(&line->chan_list, &line->task, tty,
358 line->driver->read_irq);
359
360 /* Maybe there is enough stuff pending that calling the interrupt
361 * throttles us again. In this case, line->throttled will be 1
362 * again and we shouldn't turn the interrupt back on.
363 */
364 if(!line->throttled)
365 reactivate_chan(&line->chan_list, line->driver->read_irq);
366}
367
343static irqreturn_t line_write_interrupt(int irq, void *data, 368static irqreturn_t line_write_interrupt(int irq, void *data,
344 struct pt_regs *unused) 369 struct pt_regs *unused)
345{ 370{
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 6823dc5d665c..a32ef55cb244 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -109,16 +109,6 @@ static void ssl_flush_buffer(struct tty_struct *tty)
109 return; 109 return;
110} 110}
111 111
112static void ssl_throttle(struct tty_struct * tty)
113{
114 printk(KERN_ERR "Someone should implement ssl_throttle\n");
115}
116
117static void ssl_unthrottle(struct tty_struct * tty)
118{
119 printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
120}
121
122static void ssl_stop(struct tty_struct *tty) 112static void ssl_stop(struct tty_struct *tty)
123{ 113{
124 printk(KERN_ERR "Someone should implement ssl_stop\n"); 114 printk(KERN_ERR "Someone should implement ssl_stop\n");
@@ -145,9 +135,9 @@ static struct tty_operations ssl_ops = {
145 .flush_chars = line_flush_chars, 135 .flush_chars = line_flush_chars,
146 .set_termios = line_set_termios, 136 .set_termios = line_set_termios,
147 .ioctl = line_ioctl, 137 .ioctl = line_ioctl,
138 .throttle = line_throttle,
139 .unthrottle = line_unthrottle,
148#if 0 140#if 0
149 .throttle = ssl_throttle,
150 .unthrottle = ssl_unthrottle,
151 .stop = ssl_stop, 141 .stop = ssl_stop,
152 .start = ssl_start, 142 .start = ssl_start,
153 .hangup = ssl_hangup, 143 .hangup = ssl_hangup,
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 6d4edda9b510..61db8b2fc83f 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -122,6 +122,8 @@ static struct tty_operations console_ops = {
122 .flush_chars = line_flush_chars, 122 .flush_chars = line_flush_chars,
123 .set_termios = line_set_termios, 123 .set_termios = line_set_termios,
124 .ioctl = line_ioctl, 124 .ioctl = line_ioctl,
125 .throttle = line_throttle,
126 .unthrottle = line_unthrottle,
125}; 127};
126 128
127static void uml_console_write(struct console *console, const char *string, 129static void uml_console_write(struct console *console, const char *string,
diff --git a/arch/um/include/chan_kern.h b/arch/um/include/chan_kern.h
index 84d1f64f9795..1bb5e9d94270 100644
--- a/arch/um/include/chan_kern.h
+++ b/arch/um/include/chan_kern.h
@@ -38,6 +38,8 @@ extern int console_write_chan(struct list_head *chans, const char *buf,
38 int len); 38 int len);
39extern int console_open_chan(struct line *line, struct console *co, 39extern int console_open_chan(struct line *line, struct console *co,
40 struct chan_opts *opts); 40 struct chan_opts *opts);
41extern void deactivate_chan(struct list_head *chans, int irq);
42extern void reactivate_chan(struct list_head *chans, int irq);
41extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); 43extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty);
42extern void enable_chan(struct line *line); 44extern void enable_chan(struct line *line);
43extern void close_chan(struct list_head *chans, int delay_free_irq); 45extern void close_chan(struct list_head *chans, int delay_free_irq);
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index e6cc3abfd4db..6f4d680dc1d4 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -38,6 +38,7 @@ struct line {
38 struct list_head chan_list; 38 struct list_head chan_list;
39 int valid; 39 int valid;
40 int count; 40 int count;
41 int throttled;
41 /*This lock is actually, mostly, local to*/ 42 /*This lock is actually, mostly, local to*/
42 spinlock_t lock; 43 spinlock_t lock;
43 44
@@ -60,6 +61,7 @@ struct line {
60 { init_str : str, \ 61 { init_str : str, \
61 init_pri : INIT_STATIC, \ 62 init_pri : INIT_STATIC, \
62 valid : 1, \ 63 valid : 1, \
64 throttled : 0, \
63 lock : SPIN_LOCK_UNLOCKED, \ 65 lock : SPIN_LOCK_UNLOCKED, \
64 buffer : NULL, \ 66 buffer : NULL, \
65 head : NULL, \ 67 head : NULL, \
@@ -88,6 +90,8 @@ extern void line_flush_chars(struct tty_struct *tty);
88extern int line_write_room(struct tty_struct *tty); 90extern int line_write_room(struct tty_struct *tty);
89extern int line_ioctl(struct tty_struct *tty, struct file * file, 91extern int line_ioctl(struct tty_struct *tty, struct file * file,
90 unsigned int cmd, unsigned long arg); 92 unsigned int cmd, unsigned long arg);
93extern void line_throttle(struct tty_struct *tty);
94extern void line_unthrottle(struct tty_struct *tty);
91 95
92extern char *add_xterm_umid(char *base); 96extern char *add_xterm_umid(char *base);
93extern int line_setup_irq(int fd, int input, int output, struct line *line, 97extern int line_setup_irq(int fd, int input, int output, struct line *line,