diff options
Diffstat (limited to 'arch/m68k/kernel/console.c')
-rw-r--r-- | arch/m68k/kernel/console.c | 231 |
1 files changed, 149 insertions, 82 deletions
diff --git a/arch/m68k/kernel/console.c b/arch/m68k/kernel/console.c index cac94e7d4..468ae0b59 100644 --- a/arch/m68k/kernel/console.c +++ b/arch/m68k/kernel/console.c @@ -20,7 +20,7 @@ * 'unsigned long con_init(unsigned long)' * 'int con_open(struct tty_struct *tty, struct file * filp)' * 'void con_write(struct tty_struct * tty)' - * 'void console_print(const char * b)' + * 'void vt_console_print(const char * b)' * 'void update_screen(int new_console)' * * 'void do_blank_screen(int)' @@ -103,11 +103,13 @@ * interrupt, as we use trap-gates. Hopefully all is well. */ +#include <linux/config.h> #include <linux/sched.h> #include <linux/timer.h> #include <linux/interrupt.h> #include <linux/tty.h> #include <linux/tty_flip.h> +#include <linux/console.h> #include <linux/kernel.h> #include <linux/string.h> #include <linux/errno.h> @@ -127,6 +129,7 @@ #include "../../../drivers/char/vt_kern.h" #include "../../../drivers/char/consolemap.h" #include "../../../drivers/char/selection.h" +#include "../../../drivers/char/console_struct.h" #ifndef MIN @@ -146,12 +149,13 @@ static void gotoxy(int currcons, int new_x, int new_y); static void save_cur(int currcons); static void blank_screen(void); static void unblank_screen(void); +static int con_open(struct tty_struct *, struct file *); extern void change_console(unsigned int); static inline void set_cursor(int currcons); static void reset_terminal(int currcons, int do_clear); extern void reset_vc(unsigned int new_console); extern void vt_init(void); -extern void register_console(void (*proc)(const char *)); +static void set_vesa_blanking(unsigned long arg); extern void vesa_blank(void); extern void vesa_unblank(void); extern void compute_shiftstate(void); @@ -170,6 +174,7 @@ int video_mode_512ch = 0; /* 512-character mode */ static unsigned short console_charmask = 0x0ff; static unsigned short *vc_scrbuf[MAX_NR_CONSOLES]; +struct vc vc_cons [MAX_NR_CONSOLES]; /* used by kbd_bh - set by keyboard_interrupt */ int do_poke_blanked_console = 0; @@ -178,13 +183,17 @@ static int blankinterval = 10*60*HZ; static int vesa_off_interval = 0; static int vesa_blank_mode = 0; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ -static struct vc { - struct vc_data *d; +/* + * fg_console is the current virtual console, + * last_console is the last used one, + * want_console is the console we want to switch to, + * kmsg_redirect is the console for kernel messages, + */ +int fg_console = 0; +int last_console = 0; +int want_console = -1; +int kmsg_redirect = 0; - /* might add scrmem, vt_struct, kbd at some time, - to have everything in one place - the disadvantage - would be that vc_cons etc can no longer be static */ -} vc_cons [MAX_NR_CONSOLES]; struct consw *conswitchp; #define cols (vc_cons[currcons].d->vc_cols) @@ -259,8 +268,6 @@ struct consw *conswitchp; #define vtnewvt (vt_cons[currcons]->vt_newvt) #endif -#define structsize (sizeof(struct vc_data) + sizeof(struct vt_struct)) - int vc_cons_allocated(unsigned int i) { return (i < MAX_NR_CONSOLES && vc_cons[i].d); @@ -610,8 +617,7 @@ void scrollback(int l) return; } -static void scrup(int currcons, unsigned int t, unsigned int b, - int nr) +static void scrup(int currcons, unsigned int t, unsigned int b, int nr) { unsigned short *p; int i; @@ -625,10 +631,10 @@ static void scrup(int currcons, unsigned int t, unsigned int b, p = video_mem_start + (b - nr) * cols; for (i = nr * cols; i > 0; i--) - *p++ = video_erase_char; + *p++ = video_erase_char; if (currcons != fg_console) - return; + return; /* * Arno: * Scrolling has now been moved to amicon.c where it should have @@ -801,8 +807,8 @@ static void csi_X(int currcons, int vpar) /* erase the following vpar positions if (!vpar) vpar++; - start=pos; - count=(vpar > cols-x) ? (cols-x) : vpar; + start = pos; + count = (vpar > cols-x) ? (cols-x) : vpar; if (currcons == fg_console) sw->con_clear(vc_cons[currcons].d,y,x,1,count); @@ -970,7 +976,7 @@ static void respond_string(const char * p, struct tty_struct * tty) tty_schedule_flip(tty); } -static void cursor_report(int currcons, struct tty_struct * tty) +static inline void cursor_report(int currcons, struct tty_struct * tty) { char buf[40]; @@ -997,7 +1003,7 @@ void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry) respond_string(buf, tty); } -/* invoked via ioctl(TIOCLINUX) */ +/* invoked via ioctl(TIOCLINUX) and through set_selection */ int mouse_reporting(void) { int currcons = fg_console; @@ -1005,6 +1011,56 @@ int mouse_reporting(void) return report_mouse; } +int tioclinux(struct tty_struct *tty, unsigned long arg) +{ + char type, data; + + if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE) + return -EINVAL; + if (current->tty != tty && !suser()) + return -EPERM; + if (get_user(type, (char *)arg)) + return -EFAULT; + switch (type) + { + case 2: + return set_selection(arg, tty, 1); + case 3: + return paste_selection(tty); + case 4: + do_unblank_screen(); + return 0; + case 5: + return sel_loadlut(arg); + case 6: + + /* + * Make it possible to react to Shift+Mousebutton. + * Note that 'shift_state' is an undocumented + * kernel-internal variable; programs not closely + * related to the kernel should not use this. + */ + data = shift_state; + return put_user(data, (char *) arg); + case 7: + data = mouse_reporting(); + return put_user(data, (char *) arg); + case 10: + set_vesa_blanking(arg); + return 0; + case 11: /* set kmsg redirect */ + if (!suser()) + return -EPERM; + if (get_user(data, (char *)arg+1)) + return -EFAULT; + kmsg_redirect = data; + return 0; + case 12: /* get fg_console */ + return fg_console; + } + return -EINVAL; +} + static inline unsigned short *screenpos(int currcons, int offset, int viewed) { unsigned short *p = (unsigned short *)(origin + offset); @@ -1242,18 +1298,18 @@ static void setterm_command(int currcons) } } -static void insert_char(int currcons) +static inline void insert_char(int currcons) { int i; unsigned short *p = pos; for (i = cols - x - 2; i >= 0; i--) - p[i + 1] = p[i]; + p[i + 1] = p[i]; *pos = video_erase_char; need_wrap = 0; if (currcons != fg_console) - return; + return; /* Arno: * Move the remainder of the line (-1 character) one spot to the right @@ -1277,19 +1333,19 @@ static void csi_at(int currcons, unsigned int nr) p = pos + cols - x - nr; while (--p >= pos) - p[nr] = *p; + p[nr] = *p; for (i = 0; i < nr; i++) - *++p = video_erase_char; + *++p = video_erase_char; need_wrap = 0; if (currcons != fg_console) - return; + return; sw->con_bmove (vc_cons[currcons].d, y, x, y, x + nr, 1, cols - x - nr); while (nr--) - sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff, - y, x + nr); + sw->con_putc (vc_cons[currcons].d, + video_erase_char & 0x00ff, y, x + nr); } static void csi_L(int currcons, unsigned int nr) @@ -1584,9 +1640,9 @@ static int do_con_write(struct tty_struct * tty, int from_user, */ /* Only use this for the foreground console, - where we really draw the chars */ + where we really draw the chars */ - if (count > 2 && + if (count > 2 && !decim && !utf && currcons == fg_console) { static char putcs_buf[256]; char *p = putcs_buf; @@ -1599,13 +1655,11 @@ static int do_con_write(struct tty_struct * tty, int from_user, if (nextx == cols) { sw->con_putc(vc_cons[currcons].d, *putcs_buf, y, x); - pos--; + ((unsigned short *)pos)--; need_wrap = decawm; continue; } - /* TAB TAB TAB - Arghh!!!! */ - while (count) { enable_bh(CONSOLE_BH); @@ -2068,12 +2122,13 @@ void poke_blanked_console(void) /* DPC: New version of console_print using putcs */ -void console_print(const char * b) +#ifdef CONFIG_VT_CONSOLE +void vt_console_print(const char * b, unsigned int count) { int currcons = fg_console; unsigned char c; const char *start = b; - ushort count = 0; + ushort cnt = 0; ushort myx = x; static int printing = 0; @@ -2086,7 +2141,7 @@ void console_print(const char * b) if (!vc_cons_allocated(currcons)) { /* impossible */ - printk("console_print: tty %d not allocated ??\n", currcons+1); + printk("vt_console_print: tty %d not allocated ??\n", currcons+1); printing = 0; return; } @@ -2096,52 +2151,51 @@ void console_print(const char * b) /* Contrived structure to try to emulate original need_wrap behaviour * Problems caused when we have need_wrap set on '\n' character */ - - while ((c = *(b++)) != 0) { - if (c == 10 || c == 13 || c == 8 || need_wrap) { - if ((count = b - start - 1) > 0) { - sw->con_putcs(vc_cons[currcons].d, start, count , - y, x); - x += count; - if (need_wrap) - x--; - } - - if (c == 8) { /* backspace */ - bs(currcons); - start = b; - myx = x; - continue; + + while (count-- > 0) { + c = *(b++); + if (c == 10 || c == 13 || c == 8 || need_wrap) { + if ((cnt = b - start - 1) > 0) { + sw->con_putcs(vc_cons[currcons].d, + start, cnt, y, x); + x += cnt; + if (need_wrap) + x--; + } + + if (c == 8) { /* backspace */ + bs(currcons); + start = b; + myx = x; + continue; + } + if (c != 13) + lf(currcons); + cr(currcons); + + if (c == 10 || c == 13) { + start = b; myx = x; continue; + } + + start = b-1; myx = x; + } + + *pos = c | (attr << 8); + if (myx == cols - 1) { + need_wrap = 1; + continue; } - if (c != 13) - lf(currcons); - cr(currcons); - - if (c == 10 || c == 13) { - start = b; myx = x; continue; - } - - start = b-1; myx = x; - } - - *pos = c | (attr << 8); - if (myx == cols - 1) { - need_wrap = 1; - continue; - } - pos++; - myx++; + pos++; + myx++; } - if ((count = b - start -1) > 0) { - sw->con_putcs(vc_cons[currcons].d, start, count , - y, x); - x += count; - if (x == cols) - { - x--; - need_wrap = 1; - } + if ((cnt = b - start) > 0) { + sw->con_putcs(vc_cons[currcons].d, start, cnt, y, x); + x += cnt; + if (x == cols){ + x--; + need_wrap = 1; + } } set_cursor(currcons); @@ -2149,6 +2203,18 @@ void console_print(const char * b) printing = 0; } +static int vt_console_device(void) +{ + return MKDEV(TTY_MAJOR, fg_console + 1); +} + +extern void keyboard_wait_for_keypress(void); + +struct console vt_console_driver = { + vt_console_print, do_unblank_screen, + keyboard_wait_for_keypress, vt_console_device +}; +#endif /* * con_throttle and con_unthrottle are only used for @@ -2219,7 +2285,7 @@ static void console_bh(void) */ unsigned long con_init(unsigned long kmem_start) { - char *display_desc = "????"; + const char *display_desc = "????"; unsigned int currcons = 0; extern int serial_debug; @@ -2293,14 +2359,15 @@ unsigned long con_init(unsigned long kmem_start) printable = 1; /* If "serdebug" cmd line option was present, don't register for printk */ +#ifdef CONFIG_VT_CONSOLE if (!serial_debug) - register_console(console_print); + register_console(&vt_console_driver); printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n", can_do_color ? "colour":"mono", display_desc, cols,rows, MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES); - +#endif init_bh(CONSOLE_BH, console_bh); return kmem_start; } @@ -2466,7 +2533,7 @@ static void unblank_screen(void) /* * Allocate the console screen memory. */ -int con_open(struct tty_struct *tty, struct file * filp) +static int con_open(struct tty_struct *tty, struct file * filp) { unsigned int currcons; int i; @@ -2603,7 +2670,7 @@ int con_adjust_height(unsigned long fontheight) return -EINVAL; } -void set_vesa_blanking(int arg) +static void set_vesa_blanking(unsigned long arg) { char *argp = (char *)arg + 1; unsigned int mode; |