From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from sc8-sf-mx2-b.sourceforge.net ([10.3.1.12] helo=sc8-sf-mx2.sourceforge.net) by sc8-sf-list1.sourceforge.net with esmtp (Exim 4.30) id 1BTiE9-00012M-To for user-mode-linux-devel@lists.sourceforge.net; Fri, 28 May 2004 07:20:53 -0700 Received: from hirsch.in-berlin.de ([192.109.42.6] ident=root) by sc8-sf-mx2.sourceforge.net with esmtp (TLSv1:AES256-SHA:256) (Exim 4.30) id 1BTiE8-00012o-1u for user-mode-linux-devel@lists.sourceforge.net; Fri, 28 May 2004 07:20:52 -0700 From: Gerd Knorr Message-ID: <20040528135816.GA27837@bytesex.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Subject: [uml-devel] [2.6 patch] terminal/console cleanups Sender: user-mode-linux-devel-admin@lists.sourceforge.net Errors-To: user-mode-linux-devel-admin@lists.sourceforge.net List-Unsubscribe: , List-Id: The user-mode Linux development list List-Post: List-Help: List-Subscribe: , List-Archive: Date: Fri, 28 May 2004 15:58:16 +0200 To: Jeff Dike , uml devel Hi, This is a major cleanup of the uml terminal drivers and console handling (console as in "where the kernel messages go to", not as in "linux virtual consoles). The changes in detail: (1) There is a new console driver calles "stderr" which (as the name implies) simply dumps all kernel messages to stderr. That one is registered very early in the boot process via console_initcall() and will print every almost kernel message: Both very early in the boot process and very late in shutdown. Did I mention the kernel panics for me with a kernel mode fault after the "System halted." message? ;) (2) Ditched the early-console-init hackery in stdio_console.c (open_console(NULL) + related stuff) into the waste basket, not needed any more as you can use the new stderr console driver to get the kernel messages if your kernel crashes very early in the boot process. (3) Handle console (stdio/serial) initialitation via console->setup() function, which has the nice effect that the console device receives all the kernel messages after setting up the device. (4) The (2) changes allow a number of further cleanups: As we don't open a line without a tty_struct any more we can ... * hook struct line into tty->driver_data * pass around tty_struct instead of struct line everythere * get rid of some trivial wrappers in ssl.c and stdio_console.c because we can get struct line via tty_struct all the time now. (5) Fixed a number of Documentation/CodingStyle issues within the code (not systematically, but usually just the places I was touching anyway or where it bugged me while browsing the code because it was hard to read). Looks like that cleanup also fixed some strange tty issues I've seen in the past (like console getty not responding to input sometimes, suse's /sbin/blogd causing trouble), althrough I havn't tested it that much yet. Note that with this patch applied it is strongly recommended to specify the device you want to use as console on the kernel command line. The default console is the new stderr console, which has no terminal driver accociated to it, which in turn will make the kernel complain that it can't open a initial console unless you specify one. To get something close to the old behavior use this: $ ./linux console=tty1 [ more args ] My personal favorite is still a serial console setup on hosts terminal, which can be archived this way: $ ./linux con=null ssl0=fd:0,fd:1 console=ttyS0 [ more args ] Note that it is possible to specify multiple consoles, so you can get the messages on both virtual serial line and stderr for example: $ ./linux ssl0=xterm console=ttyS0 console=stderr [ more args ] Enjoy! Gerd PS: I'm offline for a week starting in a few hours, so if you want to be sure I don't miss your reply please send a Cc: directly into my inbox. I usually scan the lists only very briefly after returning from holidays. diff -pu -ur linux-2.6.5-diff/arch/um/drivers/chan_kern.c linux-2.6.5/arch/um/drivers/chan_kern.c --- linux-2.6.5-diff/arch/um/drivers/chan_kern.c 2004-05-27 14:32:31.000000000 +0200 +++ linux-2.6.5/arch/um/drivers/chan_kern.c 2004-05-28 14:35:05.925440119 +0200 @@ -138,7 +138,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; @@ -146,13 +146,13 @@ void chan_enable_winch(struct list_head 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; @@ -161,7 +161,7 @@ void enable_chan(struct list_head *chans 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); } } @@ -189,21 +189,23 @@ int write_chan(struct list_head *chans, 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; } } - } + } return(ret); } @@ -223,6 +225,20 @@ int console_write_chan(struct list_head 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) { @@ -465,7 +481,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; @@ -491,7 +507,7 @@ void chan_interrupt(struct list_head *ch if(chan->primary){ if(tty != NULL) tty_hangup(tty); - line_disable(dev, irq); + line_disable(tty, irq); close_chan(chans); free_chan(chans); return; diff -pu -ur linux-2.6.5-diff/arch/um/drivers/line.c linux-2.6.5/arch/um/drivers/line.c --- linux-2.6.5-diff/arch/um/drivers/line.c 2004-05-27 14:32:31.000000000 +0200 +++ linux-2.6.5/arch/um/drivers/line.c 2004-05-28 14:36:19.062402336 +0200 @@ -6,6 +6,7 @@ #include "linux/sched.h" #include "linux/slab.h" #include "linux/list.h" +#include "linux/kd.h" #include "linux/interrupt.h" #include "linux/devfs_fs_kernel.h" #include "asm/uaccess.h" @@ -22,30 +23,33 @@ static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused) { - struct line *dev = data; + struct tty_struct *tty = data; + struct line *line = tty->driver_data; - if(dev->count > 0) - chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, - dev); + if (line) + chan_interrupt(&line->chan_list, &line->task, tty, irq); return IRQ_HANDLED; } static void line_timer_cb(void *arg) { - struct line *dev = arg; - - line_interrupt(dev->driver->read_irq, dev, NULL); + struct tty_struct *tty = arg; + struct line *line = tty->driver_data; + + line_interrupt(line->driver->read_irq, arg, NULL); } static int write_room(struct line *dev) { int n; - if(dev->buffer == NULL) return(LINE_BUFSIZE - 1); + if (dev->buffer == NULL) + return (LINE_BUFSIZE - 1); n = dev->head - dev->tail; - if(n <= 0) n = LINE_BUFSIZE + n; - return(n - 1); + if (n <= 0) + n = LINE_BUFSIZE + n; + return (n - 1); } static int buffer_data(struct line *line, const char *buf, int len) @@ -54,7 +58,7 @@ static int buffer_data(struct line *line if(line->buffer == NULL){ line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC); - if(line->buffer == NULL){ + if (line->buffer == NULL) { printk("buffer_data - atomic allocation failed\n"); return(0); } @@ -85,14 +89,17 @@ static int flush_buffer(struct line *lin { int n, count; - if((line->buffer == NULL) || (line->head == line->tail)) return(1); + if ((line->buffer == NULL) || (line->head == line->tail)) + return(1); - if(line->tail < line->head){ + if (line->tail < line->head) { count = line->buffer + LINE_BUFSIZE - line->head; n = write_chan(&line->chan_list, line->head, count, line->driver->write_irq); - if(n < 0) return(n); - if(n == count) line->head = line->buffer; + if (n < 0) + return(n); + if (n == count) + line->head = line->buffer; else { line->head += n; return(0); @@ -102,59 +109,55 @@ static int flush_buffer(struct line *lin count = line->tail - line->head; n = write_chan(&line->chan_list, line->head, count, line->driver->write_irq); - if(n < 0) return(n); + if (n < 0) + return(n); line->head += n; - return(line->head == line->tail); + return (line->head == line->tail); } -int line_write(struct line *lines, struct tty_struct *tty, int from_user, - const char *buf, int len) +int line_write(struct tty_struct *tty, int from_user, + const unsigned char *buf, int len) { - struct line *line; + struct line *line = tty->driver_data; char *new; unsigned long flags; - int n, err, i, ret = 0; + int n, err, ret = 0; - if(tty->stopped) return 0; + if (tty->stopped) + return 0; - if(from_user){ + if (from_user) { new = kmalloc(len, GFP_KERNEL); - if(new == NULL) - return(0); + if (new == NULL) + return 0; n = copy_from_user(new, buf, len); buf = new; - if(n == len){ + if (n == len) { len = -EFAULT; goto out_free; } - len -= n; } - i = tty->index; - line = &lines[i]; - down(&line->sem); - if(line->head != line->tail){ + if (line->head != line->tail) { local_irq_save(flags); - ret += buffer_data(line, buf, len); + ret = buffer_data(line, buf, len); err = flush_buffer(line); local_irq_restore(flags); - if(err <= 0) - goto out_up; - } - else { + if (err < 0) + ret = err; + } else { n = write_chan(&line->chan_list, buf, len, line->driver->write_irq); - if(n < 0){ + if (n < 0) { ret = n; goto out_up; } - len -= n; ret += n; - if(len > 0) + if (len > 0) ret += buffer_data(line, buf + n, len); } out_up: @@ -165,19 +168,92 @@ int line_write(struct line *lines, struc return(ret); } +void line_put_char(struct tty_struct *tty, unsigned char ch) +{ + line_write(tty, 0, &ch, sizeof(ch)); +} + +void line_set_termios(struct tty_struct *tty, struct termios * old) +{ + /* nothing */ +} + +int line_chars_in_buffer(struct tty_struct *tty) +{ + return 0; +} + +static struct { + int cmd; + char *level; + char *name; +} tty_ioctls[] = { + /* don't print these, they flood the log ... */ + { TCSBRK, NULL, "TCSBRK" }, + { TCGETS, NULL, "TCGETS" }, + { TCSETSW, NULL, "TCSETSW" }, + + /* general tty stuff */ + { TCSETS, KERN_DEBUG, "TCSETS" }, + { TCFLSH, KERN_DEBUG, "TCFLSH" }, + { TCSETSF, KERN_DEBUG, "TCSETSF" }, + { TCGETA, KERN_DEBUG, "TCGETA" }, + { TIOCMGET, KERN_DEBUG, "TIOCMGET" }, + { TCSBRKP, KERN_DEBUG, "TCSBRKP" }, + { TIOCMSET, KERN_DEBUG, "TIOCMSET" }, + + /* linux-specific ones */ + { TIOCLINUX, KERN_INFO, "TIOCLINUX" }, + { KDGKBMODE, KERN_INFO, "KDGKBMODE" }, + { KDGKBTYPE, KERN_INFO, "KDGKBTYPE" }, + { KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" }, +}; + +int line_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + int ret; + int i; + + ret = 0; + switch(cmd) { +#if 0 + case TCwhatever: + /* do something */ + break; +#endif + default: + for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++) + if (cmd == tty_ioctls[i].cmd) + break; + if (i < ARRAY_SIZE(tty_ioctls)) { + if (NULL != tty_ioctls[i].level) + printk("%s%s: %s: ioctl %s called\n", + tty_ioctls[i].level, __FUNCTION__, + tty->name, tty_ioctls[i].name); + } else { + printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n", + __FUNCTION__, tty->name, cmd); + } + ret = -ENOIOCTLCMD; + break; + } + return(ret); +} + static irqreturn_t line_write_interrupt(int irq, void *data, struct pt_regs *unused) { - struct line *dev = data; - struct tty_struct *tty = dev->tty; + struct tty_struct *tty = data; + struct line *line = tty->driver_data; int err; - err = flush_buffer(dev); + err = flush_buffer(line); if(err == 0) return(IRQ_NONE); else if(err < 0){ - dev->head = dev->buffer; - dev->tail = dev->buffer; + line->head = line->buffer; + line->tail = line->buffer; } if(tty == NULL) @@ -198,36 +274,42 @@ static irqreturn_t line_write_interrupt( return(IRQ_HANDLED); } -int line_setup_irq(int fd, int input, int output, void *data) +int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) { - struct line *line = data; + struct line *line = tty->driver_data; struct line_driver *driver = line->driver; int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM; - if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, - line_interrupt, flags, - driver->read_irq_name, line); - if(err) return(err); - if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, - line_write_interrupt, flags, - driver->write_irq_name, line); + if (input) + err = um_request_irq(driver->read_irq, fd, IRQ_READ, + line_interrupt, flags, + driver->read_irq_name, tty); + if (err) + return(err); + if (output) + err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, + line_write_interrupt, flags, + driver->write_irq_name, tty); line->have_irq = 1; return(err); } -void line_disable(struct line *line, int current_irq) +void line_disable(struct tty_struct *tty, int current_irq) { - if(!line->have_irq) return; + struct line *line = tty->driver_data; - if(line->driver->read_irq == current_irq) - free_irq_later(line->driver->read_irq, line); + if (!line->have_irq) + return; + + if (line->driver->read_irq == current_irq) + free_irq_later(line->driver->read_irq, tty); else - free_irq(line->driver->read_irq, line); + free_irq(line->driver->read_irq, tty); if(line->driver->write_irq == current_irq) - free_irq_later(line->driver->write_irq, line); + free_irq_later(line->driver->write_irq, tty); else - free_irq(line->driver->write_irq, line); + free_irq(line->driver->write_irq, tty); line->have_irq = 0; } @@ -236,73 +318,51 @@ int line_open(struct line *lines, struct struct chan_opts *opts) { struct line *line; - int n, err = 0; + int err = 0; - if(tty == NULL) n = 0; - else n = tty->index; - line = &lines[n]; + line = &lines[tty->index]; + tty->driver_data = line; down(&line->sem); - if(line->count == 0){ - if(!line->valid){ + if (tty->count == 1) { + if (!line->valid) { err = -ENODEV; goto out; } - if(list_empty(&line->chan_list)){ + if (list_empty(&line->chan_list)) { err = parse_chan_pair(line->init_str, &line->chan_list, - line->init_pri, n, opts); + line->init_pri, tty->index, opts); if(err) goto out; err = open_chan(&line->chan_list); if(err) goto out; } - enable_chan(&line->chan_list, line); - INIT_WORK(&line->task, line_timer_cb, line); + enable_chan(&line->chan_list, tty); + INIT_WORK(&line->task, line_timer_cb, tty); } if(!line->sigio){ - chan_enable_winch(&line->chan_list, line); + chan_enable_winch(&line->chan_list, tty); line->sigio = 1; } - - /* This is outside the if because the initial console is opened - * with tty == NULL - */ - line->tty = tty; - - if(tty != NULL){ - tty->driver_data = line; - chan_window_size(&line->chan_list, &tty->winsize.ws_row, - &tty->winsize.ws_col); - } - + chan_window_size(&line->chan_list, &tty->winsize.ws_row, + &tty->winsize.ws_col); line->count++; - out: + +out: up(&line->sem); return(err); } -void line_close(struct line *lines, struct tty_struct *tty) +void line_close(struct tty_struct *tty, struct file * filp) { - struct line *line; - int n; - - if(tty == NULL) n = 0; - else n = tty->index; - line = &lines[n]; + struct line *line = tty->driver_data; down(&line->sem); line->count--; - - /* I don't like this, but I can't think of anything better. What's - * going on is that the tty is in the process of being closed for - * the last time. Its count hasn't been dropped yet, so it's still - * at 1. This may happen when line->count != 0 because of the initial - * console open (without a tty) bumping it up to 1. - */ - if((line->tty != NULL) && (line->tty->count == 1)) - line->tty = NULL; - if(line->count == 0) - line_disable(line, -1); + if (tty->count == 1) { + line_disable(tty, -1); + tty->driver_data = NULL; + } up(&line->sem); } @@ -335,14 +395,15 @@ int line_setup(struct line *lines, int n n, num); return(0); } - else if(n >= 0){ - if(lines[n].count > 0){ + else if (n >= 0){ + if (lines[n].count > 0) { printk("line_setup - device %d is open\n", n); return(0); } - if(lines[n].init_pri <= INIT_ONE){ + if (lines[n].init_pri <= INIT_ONE){ lines[n].init_pri = INIT_ONE; - if(!strcmp(init, "none")) lines[n].valid = 0; + if (!strcmp(init, "none")) + lines[n].valid = 0; else { lines[n].init_str = init; lines[n].valid = 1; @@ -422,8 +483,15 @@ int line_remove(struct line *lines, int int line_write_room(struct tty_struct *tty) { struct line *dev = tty->driver_data; + int room; - return(write_room(dev)); + if (tty->stopped) + return 0; + room = write_room(dev); + if (0 == room) + printk(KERN_DEBUG "%s: %s: no room left in buffer\n", + __FUNCTION__,tty->name); + return room; } struct tty_driver *line_register_devfs(struct lines *set, @@ -490,13 +558,14 @@ struct winch { int fd; int tty_fd; int pid; - struct line *line; + struct tty_struct *tty; }; irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused) { struct winch *winch = data; struct tty_struct *tty; + struct line *line; int err; char c; @@ -513,9 +582,10 @@ irqreturn_t winch_interrupt(int irq, voi goto out; } } - tty = winch->line->tty; - if(tty != NULL){ - chan_window_size(&winch->line->chan_list, + tty = winch->tty; + line = tty->driver_data; + if (tty != NULL) { + chan_window_size(&line->chan_list, &tty->winsize.ws_row, &tty->winsize.ws_col); kill_pg(tty->pgrp, SIGWINCH, 1); @@ -529,13 +599,13 @@ irqreturn_t winch_interrupt(int irq, voi DECLARE_MUTEX(winch_handler_sem); LIST_HEAD(winch_handlers); -void register_winch_irq(int fd, int tty_fd, int pid, void *line) +void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty) { struct winch *winch; down(&winch_handler_sem); winch = kmalloc(sizeof(*winch), GFP_KERNEL); - if(winch == NULL){ + if (winch == NULL) { printk("register_winch_irq - kmalloc failed\n"); goto out; } @@ -543,7 +613,7 @@ void register_winch_irq(int fd, int tty_ .fd = fd, .tty_fd = tty_fd, .pid = pid, - .line = line }); + .tty = tty }); list_add(&winch->list, &winch_handlers); if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, @@ -568,7 +638,6 @@ static void winch_cleanup(void) os_kill_process(winch->pid, 1); } } - __uml_exitcall(winch_cleanup); char *add_xterm_umid(char *base) diff -pu -ur linux-2.6.5-diff/arch/um/drivers/pty.c linux-2.6.5/arch/um/drivers/pty.c --- linux-2.6.5-diff/arch/um/drivers/pty.c 2004-05-27 14:32:31.000000000 +0200 +++ linux-2.6.5/arch/um/drivers/pty.c 2004-05-27 23:24:59.000000000 +0200 @@ -53,7 +53,8 @@ int pts_open(int input, int output, int dev = ptsname(fd); sprintf(data->dev_name, "%s", dev); *dev_out = data->dev_name; - if(data->announce) (*data->announce)(dev, data->dev); + if (data->announce) + (*data->announce)(dev, data->dev); return(fd); } @@ -93,10 +94,13 @@ int pty_open(int input, int output, int char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx"; fd = getmaster(dev); - if(fd < 0) return(-errno); + if(fd < 0) + return(-errno); - if(data->raw) raw(fd, 0); - if(data->announce) (*data->announce)(dev, data->dev); + if(data->raw) + raw(fd, 0); + if(data->announce) + (*data->announce)(dev, data->dev); sprintf(data->dev_name, "%s", dev); *dev_out = data->dev_name; diff -pu -ur linux-2.6.5-diff/arch/um/drivers/ssl.c linux-2.6.5/arch/um/drivers/ssl.c --- linux-2.6.5-diff/arch/um/drivers/ssl.c 2004-05-27 14:32:31.000000000 +0200 +++ linux-2.6.5/arch/um/drivers/ssl.c 2004-05-28 13:25:12.534009205 +0200 @@ -54,7 +54,7 @@ static int ssl_remove(char *str); static struct line_driver driver = { .name = "UML serial line", - .device_name = "ttS", + .device_name = "ttyS", .devfs_name = "tts/", .major = TTY_MAJOR, .minor_start = 64, @@ -103,68 +103,20 @@ static int ssl_remove(char *str) int ssl_open(struct tty_struct *tty, struct file *filp) { - return(line_open(serial_lines, tty, &opts)); -} - -static void ssl_close(struct tty_struct *tty, struct file * filp) -{ - line_close(serial_lines, tty); -} - -static int ssl_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -{ - return(line_write(serial_lines, tty, from_user, buf, count)); -} - -static void ssl_put_char(struct tty_struct *tty, unsigned char ch) -{ - line_write(serial_lines, tty, 0, &ch, sizeof(ch)); + return line_open(serial_lines, tty, &opts); } +#if 0 static void ssl_flush_chars(struct tty_struct *tty) { return; } -static int ssl_chars_in_buffer(struct tty_struct *tty) -{ - return(0); -} - static void ssl_flush_buffer(struct tty_struct *tty) { return; } -static int ssl_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - int ret; - - ret = 0; - switch(cmd){ - case TCGETS: - case TCSETS: - case TCFLSH: - case TCSETSF: - case TCSETSW: - case TCGETA: - case TIOCMGET: - case TCSBRK: - case TCSBRKP: - case TIOCMSET: - ret = -ENOIOCTLCMD; - break; - default: - printk(KERN_ERR - "Unimplemented ioctl in ssl_ioctl : 0x%x\n", cmd); - ret = -ENOIOCTLCMD; - break; - } - return(ret); -} - static void ssl_throttle(struct tty_struct * tty) { printk(KERN_ERR "Someone should implement ssl_throttle\n"); @@ -175,11 +127,6 @@ static void ssl_unthrottle(struct tty_st printk(KERN_ERR "Someone should implement ssl_unthrottle\n"); } -static void ssl_set_termios(struct tty_struct *tty, - struct termios *old_termios) -{ -} - static void ssl_stop(struct tty_struct *tty) { printk(KERN_ERR "Someone should implement ssl_stop\n"); @@ -193,23 +140,26 @@ static void ssl_start(struct tty_struct void ssl_hangup(struct tty_struct *tty) { } +#endif static struct tty_operations ssl_ops = { .open = ssl_open, - .close = ssl_close, - .write = ssl_write, - .put_char = ssl_put_char, + .close = line_close, + .write = line_write, + .put_char = line_put_char, + .write_room = line_write_room, + .chars_in_buffer = line_chars_in_buffer, + .set_termios = line_set_termios, + .ioctl = line_ioctl, +#if 0 .flush_chars = ssl_flush_chars, - .chars_in_buffer = ssl_chars_in_buffer, .flush_buffer = ssl_flush_buffer, - .ioctl = ssl_ioctl, .throttle = ssl_throttle, .unthrottle = ssl_unthrottle, - .set_termios = ssl_set_termios, .stop = ssl_stop, .start = ssl_start, .hangup = ssl_hangup, - .write_room = line_write_room, +#endif }; /* Changed by ssl_init and referenced by ssl_exit, which are both serialized @@ -221,11 +171,10 @@ static void ssl_console_write(struct con unsigned len) { struct line *line = &serial_lines[c->index]; - if(ssl_init_done) - down(&line->sem); + + down(&line->sem); console_write_chan(&line->chan_list, string, len); - if(ssl_init_done) - up(&line->sem); + up(&line->sem); } static struct tty_driver *ssl_console_device(struct console *c, int *index) @@ -236,16 +185,18 @@ static struct tty_driver *ssl_console_de static int ssl_console_setup(struct console *co, char *options) { - return(0); + struct line *line = &serial_lines[co->index]; + + return console_open_chan(line,co,&opts); } static struct console ssl_cons = { - name: "ttyS", - write: ssl_console_write, - device: ssl_console_device, - setup: ssl_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = "ttyS", + .write = ssl_console_write, + .device = ssl_console_device, + .setup = ssl_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; int ssl_init(void) @@ -254,22 +205,30 @@ int ssl_init(void) printk(KERN_INFO "Initializing software serial port version %d\n", ssl_version); - ssl_driver = line_register_devfs(&lines, &driver, &ssl_ops, serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0])); lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0])); new_title = add_xterm_umid(opts.xterm_title); - if(new_title != NULL) opts.xterm_title = new_title; + if (new_title != NULL) + opts.xterm_title = new_title; - register_console(&ssl_cons); ssl_init_done = 1; + register_console(&ssl_cons); return(0); } - late_initcall(ssl_init); +static void ssl_exit(void) +{ + if (!ssl_init_done) + return; + close_lines(serial_lines, + sizeof(serial_lines)/sizeof(serial_lines[0])); +} +__uml_exitcall(ssl_exit); + static int ssl_chan_setup(char *str) { return(line_setup(serial_lines, @@ -280,15 +239,6 @@ static int ssl_chan_setup(char *str) __setup("ssl", ssl_chan_setup); __channel_help(ssl_chan_setup, "ssl"); -static void ssl_exit(void) -{ - if(!ssl_init_done) return; - close_lines(serial_lines, - sizeof(serial_lines)/sizeof(serial_lines[0])); -} - -__uml_exitcall(ssl_exit); - /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff -pu -ur linux-2.6.5-diff/arch/um/drivers/stdio_console.c linux-2.6.5/arch/um/drivers/stdio_console.c --- linux-2.6.5-diff/arch/um/drivers/stdio_console.c 2004-05-27 14:32:34.000000000 +0200 +++ linux-2.6.5/arch/um/drivers/stdio_console.c 2004-05-28 13:34:02.351720562 +0200 @@ -32,37 +32,36 @@ #define MAX_TTYS (16) +/* ----------------------------------------------------------------------------- */ +/* trivial console driver -- simply dump everything to stderr */ + +static void stderr_console_write(struct console *console, const char *string, + unsigned len) +{ + generic_write(2 /* stderr */, string, len, NULL); +} + +static struct console stderr_console = { + .name "stderr", + .write stderr_console_write, + .flags CON_PRINTBUFFER, +}; + +static int __init stderr_console_init(void) +{ + register_console(&stderr_console); + return 0; +} +console_initcall(stderr_console_init); + +/* ----------------------------------------------------------------------------- */ + /* Referenced only by tty_driver below - presumably it's locked correctly * by the tty driver. */ static struct tty_driver *console_driver; -static struct chan_ops init_console_ops = { - .type = "you shouldn't see this", - .init = NULL, - .open = NULL, - .close = NULL, - .read = NULL, - .write = NULL, - .console_write = generic_write, - .window_size = NULL, - .free = NULL, - .winch = 0, -}; - -static struct chan init_console_chan = { - .list = { }, - .primary = 1, - .input = 0, - .output = 1, - .opened = 1, - .fd = 1, - .pri = INIT_STATIC, - .ops = &init_console_ops, - .data = NULL -}; - void stdio_announce(char *dev_name, int dev) { printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev, @@ -128,79 +127,31 @@ static int con_remove(char *str) return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str)); } -static int open_console(struct tty_struct *tty) -{ - return(line_open(vts, tty, &opts)); -} - static int con_open(struct tty_struct *tty, struct file *filp) { - return(open_console(tty)); -} - -static void con_close(struct tty_struct *tty, struct file *filp) -{ - line_close(vts, tty); -} - -static int con_write(struct tty_struct *tty, int from_user, - const unsigned char *buf, int count) -{ - return(line_write(vts, tty, from_user, buf, count)); -} - -static void set_termios(struct tty_struct *tty, struct termios * old) -{ -} - -static int chars_in_buffer(struct tty_struct *tty) -{ - return(0); + return line_open(vts, tty, &opts); } static int con_init_done = 0; static struct tty_operations console_ops = { .open = con_open, - .close = con_close, - .write = con_write, - .chars_in_buffer = chars_in_buffer, - .set_termios = set_termios, + .close = line_close, + .write = line_write, .write_room = line_write_room, + .chars_in_buffer = line_chars_in_buffer, + .set_termios = line_set_termios, + .ioctl = line_ioctl, }; -int stdio_init(void) -{ - char *new_title; - - printk(KERN_INFO "Initializing stdio console driver\n"); - - console_driver = line_register_devfs(&console_lines, &driver, - &console_ops, vts, - sizeof(vts)/sizeof(vts[0])); - - lines_init(vts, sizeof(vts)/sizeof(vts[0])); - - new_title = add_xterm_umid(opts.xterm_title); - if(new_title != NULL) opts.xterm_title = new_title; - - open_console(NULL); - con_init_done = 1; - return(0); -} - -late_initcall(stdio_init); - static void console_write(struct console *console, const char *string, unsigned len) { struct line *line = &vts[console->index]; - if(con_init_done) - down(&line->sem); + down(&line->sem); console_write_chan(&line->chan_list, string, len); - if(con_init_done) - up(&line->sem); + up(&line->sem); } static struct tty_driver *console_device(struct console *c, int *index) @@ -211,44 +162,57 @@ static struct tty_driver *console_device static int console_setup(struct console *co, char *options) { - return(0); + struct line *line = &vts[co->index]; + + return console_open_chan(line,co,&opts); } static struct console stdiocons = { - name: "tty", - write: console_write, - device: console_device, - setup: console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = "tty", + .write = console_write, + .device = console_device, + .setup = console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &vts, }; -static int __init stdio_console_init(void) +int stdio_init(void) { - INIT_LIST_HEAD(&vts[0].chan_list); - list_add(&init_console_chan.list, &vts[0].chan_list); + char *new_title; + + printk(KERN_INFO "Initializing stdio console driver\n"); + console_driver = line_register_devfs(&console_lines, &driver, + &console_ops, vts, + sizeof(vts)/sizeof(vts[0])); + + lines_init(vts, sizeof(vts)/sizeof(vts[0])); + + new_title = add_xterm_umid(opts.xterm_title); + if(new_title != NULL) + opts.xterm_title = new_title; + + con_init_done = 1; register_console(&stdiocons); return(0); } +late_initcall(stdio_init); -console_initcall(stdio_console_init); +static void console_exit(void) +{ + if (!con_init_done) + return; + close_lines(vts, sizeof(vts)/sizeof(vts[0])); +} +__uml_exitcall(console_exit); static int console_chan_setup(char *str) { return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1)); } - __setup("con", console_chan_setup); __channel_help(console_chan_setup, "con"); -static void console_exit(void) -{ - if(!con_init_done) return; - close_lines(vts, sizeof(vts)/sizeof(vts[0])); -} - -__uml_exitcall(console_exit); - /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff -pu -ur linux-2.6.5-diff/arch/um/drivers/xterm.c linux-2.6.5/arch/um/drivers/xterm.c --- linux-2.6.5-diff/arch/um/drivers/xterm.c 2004-05-27 14:32:31.000000000 +0200 +++ linux-2.6.5/arch/um/drivers/xterm.c 2004-05-28 13:33:48.887938834 +0200 @@ -125,9 +125,9 @@ int xterm_open(int input, int output, in if(data->stack == 0) free_stack(stack, 0); - if(data->direct_rcv) + if (data->direct_rcv) { new = os_rcv_fd(fd, &data->helper_pid); - else { + } else { err = os_set_fd_block(fd, 0); if(err < 0){ printk("xterm_open : failed to set descriptor " diff -pu -ur linux-2.6.5-diff/arch/um/include/chan_kern.h linux-2.6.5/arch/um/include/chan_kern.h --- linux-2.6.5-diff/arch/um/include/chan_kern.h 2004-04-04 18:10:23.000000000 +0200 +++ linux-2.6.5/arch/um/include/chan_kern.h 2004-05-28 14:36:14.125214969 +0200 @@ -8,7 +8,9 @@ #include "linux/tty.h" #include "linux/list.h" +#include "linux/console.h" #include "chan_user.h" +#include "line.h" struct chan { struct list_head list; @@ -24,7 +26,7 @@ struct chan { }; extern 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); extern int parse_chan_pair(char *str, struct list_head *chans, int pri, int device, struct chan_opts *opts); extern int open_chan(struct list_head *chans); @@ -32,9 +34,11 @@ extern int write_chan(struct list_head * int write_irq); extern int console_write_chan(struct list_head *chans, const char *buf, int len); +extern int console_open_chan(struct line *line, struct console *co, + struct chan_opts *opts); extern void close_chan(struct list_head *chans); -extern void chan_enable_winch(struct list_head *chans, void *line); -extern void enable_chan(struct list_head *chans, void *data); +extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); +extern void enable_chan(struct list_head *chans, struct tty_struct *tty); extern int chan_window_size(struct list_head *chans, unsigned short *rows_out, unsigned short *cols_out); diff -pu -ur linux-2.6.5-diff/arch/um/include/chan_user.h linux-2.6.5/arch/um/include/chan_user.h --- linux-2.6.5-diff/arch/um/include/chan_user.h 2004-04-04 18:10:29.000000000 +0200 +++ linux-2.6.5/arch/um/include/chan_user.h 2004-05-28 14:36:10.499811689 +0200 @@ -42,8 +42,8 @@ extern int generic_window_size(int fd, v unsigned short *cols_out); extern void generic_free(void *data); -extern void register_winch(int fd, void *device_data); -extern void register_winch_irq(int fd, int tty_fd, int pid, void *line); +extern void register_winch(int fd, struct tty_struct *tty); +extern void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty); #define __channel_help(fn, prefix) \ __uml_help(fn, prefix "[0-9]*=\n" \ diff -pu -ur linux-2.6.5-diff/arch/um/include/line.h linux-2.6.5/arch/um/include/line.h --- linux-2.6.5-diff/arch/um/include/line.h 2004-05-27 14:32:31.000000000 +0200 +++ linux-2.6.5/arch/um/include/line.h 2004-05-27 22:22:57.000000000 +0200 @@ -37,7 +37,6 @@ struct line { struct list_head chan_list; int valid; int count; - struct tty_struct *tty; struct semaphore sem; char *buffer; char *head; @@ -53,8 +52,6 @@ struct line { init_pri : INIT_STATIC, \ chan_list : { }, \ valid : 1, \ - count : 0, \ - tty : NULL, \ sem : { }, \ buffer : NULL, \ head : NULL, \ @@ -69,18 +66,23 @@ struct lines { #define LINES_INIT(n) { num : n } -extern void line_close(struct line *lines, struct tty_struct *tty); +extern void line_close(struct tty_struct *tty, struct file * filp); extern int line_open(struct line *lines, struct tty_struct *tty, struct chan_opts *opts); extern int line_setup(struct line *lines, int num, char *init, int all_allowed); -extern int line_write(struct line *line, struct tty_struct *tty, int from_user, - const char *buf, int len); +extern int line_write(struct tty_struct *tty, int from_user, + const unsigned char *buf, int len); +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 int line_chars_in_buffer(struct tty_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 char *add_xterm_umid(char *base); -extern int line_setup_irq(int fd, int input, int output, void *data); +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_disable(struct line *line, int current_irq); +extern void line_disable(struct tty_struct *tty, int current_irq); extern struct tty_driver * line_register_devfs(struct lines *set, struct line_driver *line_driver, struct tty_operations *driver, ------------------------------------------------------- This SF.Net email is sponsored by: Oracle 10g Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE. http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click _______________________________________________ User-mode-linux-devel mailing list User-mode-linux-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel