Commit b97b77cc authored by Paolo 'Blaisorblade' Giarrusso's avatar Paolo 'Blaisorblade' Giarrusso Committed by Linus Torvalds

[PATCH] uml: redo console locking

Fix some console locking problems (including scheduling in atomic) and various
reorderings and cleanup in that code.  Not yet ready for 2.6.12 probably.
Signed-off-by: default avatarPaolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 80f95078
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#ifdef CONFIG_NOCONFIG_CHAN #ifdef CONFIG_NOCONFIG_CHAN
static void *not_configged_init(char *str, int device, struct chan_opts *opts) 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 " printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n"); "UML\n");
return(NULL); return(NULL);
} }
...@@ -30,27 +30,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts) ...@@ -30,27 +30,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
static int not_configged_open(int input, int output, int primary, void *data, static int not_configged_open(int input, int output, int primary, void *data,
char **dev_out) char **dev_out)
{ {
printk(KERN_ERR "Using a channel type which is configured out of " printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n"); "UML\n");
return(-ENODEV); return(-ENODEV);
} }
static void not_configged_close(int fd, void *data) static void not_configged_close(int fd, void *data)
{ {
printk(KERN_ERR "Using a channel type which is configured out of " printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n"); "UML\n");
} }
static int not_configged_read(int fd, char *c_out, void *data) static int not_configged_read(int fd, char *c_out, void *data)
{ {
printk(KERN_ERR "Using a channel type which is configured out of " printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n"); "UML\n");
return(-EIO); return(-EIO);
} }
static int not_configged_write(int fd, const char *buf, int len, void *data) static int not_configged_write(int fd, const char *buf, int len, void *data)
{ {
printk(KERN_ERR "Using a channel type which is configured out of " printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n"); "UML\n");
return(-EIO); return(-EIO);
} }
...@@ -58,7 +58,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data) ...@@ -58,7 +58,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
static int not_configged_console_write(int fd, const char *buf, int len, static int not_configged_console_write(int fd, const char *buf, int len,
void *data) void *data)
{ {
printk(KERN_ERR "Using a channel type which is configured out of " printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n"); "UML\n");
return(-EIO); return(-EIO);
} }
...@@ -66,14 +66,14 @@ static int not_configged_console_write(int fd, const char *buf, int len, ...@@ -66,14 +66,14 @@ static int not_configged_console_write(int fd, const char *buf, int len,
static int not_configged_window_size(int fd, void *data, unsigned short *rows, static int not_configged_window_size(int fd, void *data, unsigned short *rows,
unsigned short *cols) unsigned short *cols)
{ {
printk(KERN_ERR "Using a channel type which is configured out of " printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n"); "UML\n");
return(-ENODEV); return(-ENODEV);
} }
static void not_configged_free(void *data) static void not_configged_free(void *data)
{ {
printk(KERN_ERR "Using a channel type which is configured out of " printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n"); "UML\n");
} }
......
This diff is collapsed.
...@@ -107,11 +107,6 @@ int ssl_open(struct tty_struct *tty, struct file *filp) ...@@ -107,11 +107,6 @@ int ssl_open(struct tty_struct *tty, struct file *filp)
} }
#if 0 #if 0
static int ssl_chars_in_buffer(struct tty_struct *tty)
{
return(0);
}
static void ssl_flush_buffer(struct tty_struct *tty) static void ssl_flush_buffer(struct tty_struct *tty)
{ {
return; return;
...@@ -149,11 +144,11 @@ static struct tty_operations ssl_ops = { ...@@ -149,11 +144,11 @@ static struct tty_operations ssl_ops = {
.put_char = line_put_char, .put_char = line_put_char,
.write_room = line_write_room, .write_room = line_write_room,
.chars_in_buffer = line_chars_in_buffer, .chars_in_buffer = line_chars_in_buffer,
.flush_buffer = line_flush_buffer,
.flush_chars = line_flush_chars,
.set_termios = line_set_termios, .set_termios = line_set_termios,
.ioctl = line_ioctl, .ioctl = line_ioctl,
#if 0 #if 0
.flush_chars = ssl_flush_chars,
.flush_buffer = ssl_flush_buffer,
.throttle = ssl_throttle, .throttle = ssl_throttle,
.unthrottle = ssl_unthrottle, .unthrottle = ssl_unthrottle,
.stop = ssl_stop, .stop = ssl_stop,
...@@ -171,10 +166,11 @@ static void ssl_console_write(struct console *c, const char *string, ...@@ -171,10 +166,11 @@ static void ssl_console_write(struct console *c, const char *string,
unsigned len) unsigned len)
{ {
struct line *line = &serial_lines[c->index]; struct line *line = &serial_lines[c->index];
unsigned long flags;
down(&line->sem); spin_lock_irqsave(&line->lock, flags);
console_write_chan(&line->chan_list, string, len); console_write_chan(&line->chan_list, string, len);
up(&line->sem); spin_unlock_irqrestore(&line->lock, flags);
} }
static struct tty_driver *ssl_console_device(struct console *c, int *index) static struct tty_driver *ssl_console_device(struct console *c, int *index)
...@@ -238,14 +234,3 @@ static int ssl_chan_setup(char *str) ...@@ -238,14 +234,3 @@ static int ssl_chan_setup(char *str)
__setup("ssl", ssl_chan_setup); __setup("ssl", ssl_chan_setup);
__channel_help(ssl_chan_setup, "ssl"); __channel_help(ssl_chan_setup, "ssl");
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
...@@ -116,8 +116,11 @@ static struct tty_operations console_ops = { ...@@ -116,8 +116,11 @@ static struct tty_operations console_ops = {
.open = con_open, .open = con_open,
.close = line_close, .close = line_close,
.write = line_write, .write = line_write,
.put_char = line_put_char,
.write_room = line_write_room, .write_room = line_write_room,
.chars_in_buffer = line_chars_in_buffer, .chars_in_buffer = line_chars_in_buffer,
.flush_buffer = line_flush_buffer,
.flush_chars = line_flush_chars,
.set_termios = line_set_termios, .set_termios = line_set_termios,
.ioctl = line_ioctl, .ioctl = line_ioctl,
}; };
...@@ -126,10 +129,11 @@ static void uml_console_write(struct console *console, const char *string, ...@@ -126,10 +129,11 @@ static void uml_console_write(struct console *console, const char *string,
unsigned len) unsigned len)
{ {
struct line *line = &vts[console->index]; struct line *line = &vts[console->index];
unsigned long flags;
down(&line->sem); spin_lock_irqsave(&line->lock, flags);
console_write_chan(&line->chan_list, string, len); console_write_chan(&line->chan_list, string, len);
up(&line->sem); spin_unlock_irqrestore(&line->lock, flags);
} }
static struct tty_driver *uml_console_device(struct console *c, int *index) static struct tty_driver *uml_console_device(struct console *c, int *index)
...@@ -192,14 +196,3 @@ static int console_chan_setup(char *str) ...@@ -192,14 +196,3 @@ static int console_chan_setup(char *str)
} }
__setup("con", console_chan_setup); __setup("con", console_chan_setup);
__channel_help(console_chan_setup, "con"); __channel_help(console_chan_setup, "con");
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include "linux/workqueue.h" #include "linux/workqueue.h"
#include "linux/tty.h" #include "linux/tty.h"
#include "linux/interrupt.h" #include "linux/interrupt.h"
#include "asm/semaphore.h" #include "linux/spinlock.h"
#include "chan_user.h" #include "chan_user.h"
#include "mconsole_kern.h" #include "mconsole_kern.h"
...@@ -37,10 +37,18 @@ struct line { ...@@ -37,10 +37,18 @@ struct line {
struct list_head chan_list; struct list_head chan_list;
int valid; int valid;
int count; int count;
struct semaphore sem; /*This lock is actually, mostly, local to*/
spinlock_t lock;
/* Yes, this is a real circular buffer.
* XXX: And this should become a struct kfifo!
*
* buffer points to a buffer allocated on demand, of length
* LINE_BUFSIZE, head to the start of the ring, tail to the end.*/
char *buffer; char *buffer;
char *head; char *head;
char *tail; char *tail;
int sigio; int sigio;
struct work_struct task; struct work_struct task;
struct line_driver *driver; struct line_driver *driver;
...@@ -52,7 +60,6 @@ struct line { ...@@ -52,7 +60,6 @@ struct line {
init_pri : INIT_STATIC, \ init_pri : INIT_STATIC, \
chan_list : { }, \ chan_list : { }, \
valid : 1, \ valid : 1, \
sem : { }, \
buffer : NULL, \ buffer : NULL, \
head : NULL, \ head : NULL, \
tail : NULL, \ tail : NULL, \
...@@ -69,15 +76,18 @@ struct lines { ...@@ -69,15 +76,18 @@ struct lines {
extern void line_close(struct tty_struct *tty, struct file * filp); extern void line_close(struct tty_struct *tty, struct file * filp);
extern int line_open(struct line *lines, struct tty_struct *tty, extern int line_open(struct line *lines, struct tty_struct *tty,
struct chan_opts *opts); struct chan_opts *opts);
extern int line_setup(struct line *lines, int num, char *init, extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init,
int all_allowed); int all_allowed);
extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len);
extern void line_put_char(struct tty_struct *tty, unsigned char ch); extern void line_put_char(struct tty_struct *tty, unsigned char ch);
extern void line_set_termios(struct tty_struct *tty, struct termios * old); extern void line_set_termios(struct tty_struct *tty, struct termios * old);
extern int line_chars_in_buffer(struct tty_struct *tty); extern int line_chars_in_buffer(struct tty_struct *tty);
extern void line_flush_buffer(struct tty_struct *tty);
extern void line_flush_chars(struct tty_struct *tty);
extern int line_write_room(struct tty_struct *tty); extern int line_write_room(struct tty_struct *tty);
extern int line_ioctl(struct tty_struct *tty, struct file * file, extern int line_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
extern char *add_xterm_umid(char *base); extern char *add_xterm_umid(char *base);
extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty); extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty);
extern void line_close_chan(struct line *line); extern void line_close_chan(struct line *line);
...@@ -89,20 +99,10 @@ extern struct tty_driver * line_register_devfs(struct lines *set, ...@@ -89,20 +99,10 @@ extern struct tty_driver * line_register_devfs(struct lines *set,
int nlines); int nlines);
extern void lines_init(struct line *lines, int nlines); extern void lines_init(struct line *lines, int nlines);
extern void close_lines(struct line *lines, int nlines); extern void close_lines(struct line *lines, int nlines);
extern int line_config(struct line *lines, int num, char *str);
extern int line_remove(struct line *lines, int num, char *str); extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str);
extern int line_get_config(char *dev, struct line *lines, int num, char *str, extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str);
extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str,
int size, char **error_out); int size, char **error_out);
#endif #endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment