Update of /cvsroot/linuxconsole/ruby/linux/drivers/char In directory usw-pr-cvs1:/tmp/cvs-serv3286 Modified Files: consolemap.c decvte.c keyboard.c selection.c tty_io.c vc_screen.c vt.c vt_ioctl.c Log Message: Synced to console BK Index: consolemap.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/char/consolemap.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- consolemap.c 30 Oct 2002 17:50:40 -0000 1.13 +++ consolemap.c 1 Nov 2002 23:27:32 -0000 1.14 @@ -9,9 +9,6 @@ * Support for multiple unimaps by Jakub Jelinek <jj...@ul...>, July 1998 * * Fix bug in inverse translation. Stanislav Voronyi <st...@cn...>, Dec 1998 - * - * Adapted for selection in Unicode by <ed...@ra...>, January 1999 - * */ #include <linux/errno.h> @@ -23,282 +20,230 @@ #include <linux/vt_kern.h> [...1131 lines suppressed...] -void __init console_map_init(void) +void __init +console_map_init(void) { struct vt_struct *vt = vt_cons; int i; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + struct vc_data *vc = vt->vc_cons[i]; - while (vt) { - if (!vt->kmalloced && !*vt->vc_cons[0]->vc_uni_pagedir_loc) - con_set_default_unimap(vt->vc_cons[0]); - vt = vt->next; + if (vc && !*vc->vc_uni_pagedir_loc) + con_set_default_unimap(vc); } - for (i = 0; i < 4; i++) - set_inverse_translations(i); } Index: decvte.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/char/decvte.c,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- decvte.c 30 Oct 2002 17:45:06 -0000 1.21 +++ decvte.c 1 Nov 2002 23:27:32 -0000 1.22 @@ -96,10 +96,7 @@ * if below scrolling region */ if (y + 1 == bottom) - if (top == 0 && bottom == video_num_lines) - scroll_up(vc, 1); - else - scroll_region_up(vc, top, bottom, 1); + scroll_region_up(vc, top, bottom, 1); else if (y < video_num_lines - 1) { y++; pos += video_size_row; @@ -116,10 +113,7 @@ * if above scrolling region */ if (y == top) - if (top == 0 && bottom == video_num_lines) - scroll_down(vc, 1); - else - scroll_region_down(vc, top, bottom, 1); + scroll_region_down(vc, top, bottom, 1); else if (y > 0) { y--; pos -= video_size_row; @@ -225,7 +219,7 @@ clear_region(vc, 0, y, x + 1, 1); break; case 2: /* erase whole display */ - count = screensize; + count = video_num_columns * video_num_lines; start = (unsigned short *) origin; clear_region(vc, 0, 0, video_num_columns, video_num_lines); break; @@ -1029,7 +1023,6 @@ cursor_type = CUR_DEFAULT; complement_mask = s_complement_mask; - update_cursor_attr(vc); default_attr(vc); update_attr(vc); @@ -1549,7 +1542,6 @@ else cursor_type = CUR_DEFAULT; priv4 = 0; - update_cursor_attr(vc); return; } break; @@ -1956,7 +1948,7 @@ vte_ed(vc, 2); video_erase_char = (video_erase_char & 0xff00) | ' '; - do_update_region(vc, origin, screensize); + do_update_region(vc, origin, screenbuf_size / 2); } return; case ESgzd4: Index: keyboard.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/char/keyboard.c,v retrieving revision 1.78 retrieving revision 1.79 diff -u -d -r1.78 -r1.79 --- keyboard.c 30 Oct 2002 18:17:20 -0000 1.78 +++ keyboard.c 1 Nov 2002 23:27:32 -0000 1.79 @@ -271,37 +271,6 @@ } /* - * A note on character conversion: - * - * A keymap maps keycodes to keysyms, which, at present, are 16-bit - * values. If a keysym is < 0xf000 then it specifies a 16-bit Unicode - * character to be queued. If a keysym is >= 0xf000, then 0xf000 is - * subtracted to give a pair of octets, extracted by KTYP and KVAL. - * The KTYP is used as an index into key_handler[] to give a function - * which handles the KVAL. The "normal" key_handler is k_self, which - * treats the KVAL as an 8-bit character to be queued. - * - * When a 16-bit Unicode character is queued it is converted to UTF-8 - * if the keyboard is in Unicode mode; otherwise it is converted to an - * 8-bit character using the current ACM (see consolemap.c). An 8-bit - * character is assumed to be in the character set defined by the - * current ACM, so it is queued unchanged if the keyboard is in 8-bit - * mode; otherwise it is converted using the inverse ACM. - * - * The handling of diacritics uses 8-bit characters, which are - * converted using the inverse ACM, when in Unicode mode. The strings - * bound to function keys are not converted, so they may already - * contain UTF-8. Codes entered using do_ascii() treated as 16-bit and - * converted to UTF-8 in Unicode mode; otherwise they are treated as - * 8-bit and queued unchanged. - * - * Since KTYP is not used in the case of Unicode keysyms, it is not - * possible to use KT_LETTER to implement CapsLock. Either use 8-bit - * keysyms with an appropriate ACM or use the work-around proposed in - * k_lock(). - */ - -/* * Many other routines do put_queue, but I think either * they produce ASCII, or they produce some user-assigned * string, and in both cases we might assume that it is @@ -325,29 +294,6 @@ } } -void put_unicode(struct vc_data *vc, u16 uc) -{ - if (vc->kbd_table.kbdmode == VC_UNICODE) - to_utf8(vc, uc); - else if ((uc & ~0x9f) == 0 || uc == 127) - /* Don't translate control chars */ - put_queue(vc, uc); - else { - unsigned char c; - c = inverse_translate(vc->display_fg->fg_console->vc_translate, uc); - if (c) put_queue(vc, c); - } -} - -static void put_8bit(struct vc_data *vc, u8 c) -{ - /* Don't translate control chars */ - if (vc->kbd_table.kbdmode != VC_UNICODE || c < 32 || c == 127) - put_queue(vc, c); - else - to_utf8(vc, get_acm(vc->display_fg->fg_console->vc_translate)[c]); -} - /* * Called after returning from RAW mode or when changing consoles - recompute * shift_down[] and shift_state from key_down[] maybe called when keymap is @@ -408,7 +354,7 @@ if (ch == ' ' || ch == d) return d; - put_8bit(vc, d); + put_queue(vc, d); return ch; } @@ -418,7 +364,7 @@ static void fn_enter(struct vc_data *vc) { if (diacr) { - put_8bit(vc, diacr); + put_queue(vc, diacr); diacr = 0; } put_queue(vc, 13); @@ -486,6 +432,7 @@ static void fn_lastcons(struct vc_data *vc) { + /* switch to the last used console, ChN */ set_console(vc->display_fg->last_console); } @@ -533,25 +480,12 @@ static void fn_scroll_forw(struct vc_data *vc) { - //scroll_down(vc, 0); - if (vc->vc_visible_origin < vc->vc_origin) { - vc->vc_visible_origin =+ vc->vc_screensize; - do_update_region(vc, vc->vc_visible_origin, vc->vc_screensize); -// scroll_down(vc, vc->vc_rows/2); - } + scroll_down(vc, 0); } static void fn_scroll_back(struct vc_data *vc) { - //scroll_up(vc, 0); - unsigned short *p = (unsigned short *) vc->vc_visible_origin - vc->vc_screensize; - unsigned long q = (unsigned long) p; - - if (q >= ((unsigned long) vc->vc_screenbuf)) { - vc->vc_visible_origin = q; - do_update_region(vc, vc->vc_visible_origin, vc->vc_screensize); -// scroll_up(vc, vc->vc_rows/2); - } + scroll_up(vc, 0); } static void fn_show_mem(struct vc_data *vc) @@ -637,7 +571,7 @@ diacr = value; return; } - put_8bit(vc, value); + put_queue(vc, value); } /* @@ -743,7 +677,7 @@ return; } - put_8bit(vc, pad_chars[value]); + put_queue(vc, pad_chars[value]); if (value == KVAL(K_PENTER) && get_kbd_mode(vc->kbd_table, VC_CRLF)) put_queue(vc, 10); } @@ -782,7 +716,7 @@ /* kludge */ if (up_flag && shift_state != old_state && npadch != -1) { if (vc->kbd_table.kbdmode == VC_UNICODE) - put_unicode(vc, npadch & 0xffff); + to_utf8(vc, npadch & 0xffff); else put_queue(vc, npadch & 0xff); npadch = -1; @@ -827,21 +761,6 @@ { if (up_flag || rep) return; -/* - if (value >= NR_LOCK) { - * - * Change the lock state and - * set the CapsLock LED to the new state - * - unsigned char mask; - - mask = 1 << (value -= NR_LOCK); - if ((vc->kbd_table.lockstate ^= mask) & mask) - set_kbd_led(&vc->kbd_table, VC_CAPSLOCK); - else - clr_kbd_led(&vc->kbd_table, VC_CAPSLOCK); - } else { - * Just change the lock state */ chg_kbd_lock(vc->kbd_table, value); } @@ -1152,17 +1071,17 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, unsigned int keycode, int down) { - struct vt_struct *vt = (struct vt_struct *) handle->private; + struct vt_struct *vt = vt_cons; - if ((event_type != EV_KEY) || !vt || !vt->fg_console->vc_kam) + if ((event_type != EV_KEY) || !vt) return; kbd_keycode(vt, keycode, down); tasklet_schedule(&keyboard_tasklet); + do_poke_blanked_console = 1; schedule_work(&vt->vt_work); } static char kbd_name[] = "kbd"; -static int first_time; /* * When a keyboard (or other input device) is found, the kbd_connect @@ -1196,25 +1115,10 @@ handle->dev = dev; handle->handler = handler; handle->name = kbd_name; - - if (!first_time) { - first_time = 1; - vt = admin_vt; - } - - while (vt) { - if (!vt->keyboard) { - vt->keyboard = handle; - handle->private = vt; - vt_map_input(vt); - /* enable receieving key events for each VC */ - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { - vc = find_vc(vt->first_vc + i); - if (vc) vc->vc_kam = 1; - } - break; - } else - vt = vt->next; + if (!vt->keyboard) { + vt->keyboard = handle; + handle->private = vt; + vt_map_input(vt); } input_open_device(handle); return handle; @@ -1223,15 +1127,8 @@ static void kbd_disconnect(struct input_handle *handle) { struct vt_struct *vt = handle->private; - struct vc_data *vc; - int i; if (vt && vt->keyboard == handle) { - /* disable receieving key events for each VC */ - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { - vc = find_vc(vt->first_vc + i); - if (vc) vc->vc_kam = 1; - } vt->keyboard = NULL; handle->private = NULL; } Index: selection.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/char/selection.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- selection.c 17 Oct 2001 17:00:13 -0000 1.14 +++ selection.c 1 Nov 2002 23:27:32 -0000 1.15 @@ -9,8 +9,6 @@ * 'int sel_loadlut(const unsigned long arg)' * * Now that /dev/vcs exists, most of this can disappear again. - * - * Adapted for selection in Unicode by <ed...@ra...>, January 1999 */ #include <linux/module.h> @@ -35,45 +33,49 @@ /* Variables for selection control. */ /* Use a dynamic buffer, instead of static (Dec 1994) */ -int sel_cons; /* must not be disallocated */ + int sel_cons; /* must not be disallocated */ static volatile int sel_start = -1; /* cleared by clear_selection */ static int sel_end; static int sel_buffer_lth; -static u16 *sel_buffer; +static char *sel_buffer; /* clear_selection, highlight and highlight_pointer can be called from interrupt (via scrollback/front) */ /* set reverse video on characters s-e of console with selection. */ -inline static void highlight(const int s, const int e) { - invert_screen(find_vc(sel_cons), s, e-s+2, 1); -} - -/* use complementary color to show the pointer */ -inline static void highlight_pointer(const int where) { - complement_pos(find_vc(sel_cons), where); +inline static void +highlight(const int s, const int e) { + invert_screen(vt_cons->vc_cons[sel_cons], s, e-s+2, 1); } -/* used by selection */ u16 screen_glyph(struct vc_data *vc, int offset) { - u16 w = scr_readw(screenpos(vc, offset, 1)); u16 c = w & 0xff; + u16 w = scr_readw(screenpos(vc, offset, 1)); + u16 c = w & 0xff; - if (w & vc->vc_hi_font_mask) - c |= 0x100; - return c; -} + if (w & vc->vc_hi_font_mask) + c |= 0x100; + return c; +} -static u16 sel_pos(int n) + +/* use complementary color to show the pointer */ +inline static void +highlight_pointer(const int where) { + complement_pos(vt_cons->vc_cons[sel_cons], where); +} + +static unsigned char sel_pos(int n) { - return inverse_convert(find_vc(sel_cons), screen_glyph(find_vc(sel_cons), n)); + return inverse_translate(vt_cons->vc_cons[sel_cons], screen_glyph(vt_cons->vc_cons[sel_cons], n)); } /* * remove the current selection highlight, if any, * from the console holding the selection. */ -void clear_selection(void) { +void clear_selection(void) +{ highlight_pointer(-1); /* hide the pointer */ if (sel_start != -1) { highlight(sel_start, sel_end); @@ -96,9 +98,8 @@ 0xFF7FFFFF /* latin-1 accented letters, not division sign */ }; -static inline int inword(const u16 c) { - /* Everything over 0xff is considered alphabetic! */ - return c >= 0x100 || ( inwordLut[c>>5] >> (c & 0x1F) ) & 1; +static inline int inword(const unsigned char c) { + return ( inwordLut[c>>5] >> (c & 0x1F) ) & 1; } /* set inwordLut contents. Invoked by ioctl(). */ @@ -124,10 +125,10 @@ { struct vc_data *vc = (struct vc_data *) tty->driver_data; int sel_mode, new_sel_start, new_sel_end, spc; - u16 *bp, *obp; + char *bp, *obp; int i, ps, pe; - u16 ucs; + unblank_screen(); poke_blanked_console(vc->display_fg); { unsigned short *args, xs, ys, xe, ye; @@ -162,8 +163,8 @@ return 0; } - if (mouse_reporting(tty) && (sel_mode & 16)) { - mouse_report(tty, sel_mode & 15, xs, ys); + if (mouse_reporting(vc) && (sel_mode & 16)) { + mouse_report(vc, sel_mode & 15, xs, ys); return 0; } } @@ -261,7 +262,7 @@ sel_end = new_sel_end; /* Allocate a new buffer before freeing the old one ... */ - bp = kmalloc(((sel_end-sel_start)/2+1) * sizeof(u16), GFP_KERNEL); + bp = kmalloc((sel_end-sel_start)/2+1, GFP_KERNEL); if (!bp) { printk(KERN_WARNING "selection: kmalloc() failed\n"); clear_selection(); @@ -273,9 +274,8 @@ obp = bp; for (i = sel_start; i <= sel_end; i += 2) { - ucs = sel_pos(i); - *bp++ = ucs; - if (!isspace(ucs)) + *bp = sel_pos(i); + if (!isspace(*bp++)) obp = bp; if (! ((i + 2) % vc->vc_size_row)) { /* strip trailing blanks from line and add newline, @@ -298,75 +298,24 @@ int paste_selection(struct tty_struct *tty) { struct vc_data *vc = (struct vc_data *) tty->driver_data; - unsigned char *paste_buffer, *bp, *p; + int pasted = 0, count; DECLARE_WAITQUEUE(wait, current); - int utf, count; - - if (!sel_buffer || !sel_buffer_lth) return 0; - - /* Paste UTF-8 iff the keyboard is in UTF-8 mode */ - utf = (vc->display_fg->fg_console->kbd_table.kbdmode == VC_UNICODE); - - /* Make a paste buffer containing an appropriate translation - of the selection buffer */ - paste_buffer = kmalloc(utf ? sel_buffer_lth*3 : sel_buffer_lth, GFP_KERNEL); - if (!paste_buffer) { - printk(KERN_WARNING "selection: kmalloc() failed\n"); - return -ENOMEM; - } - - bp = paste_buffer; - if (utf) { - /* convert to UTF-8 */ - int i, ucs; - - for (i = 0; i < sel_buffer_lth; i++) { - ucs = sel_buffer[i]; - /* The following code should at some point - be merged with to_utf8() in keyboard.c */ - if (!(ucs & ~0x7f)) /* 0?????? */ - *bp++ = ucs; - else if (!(ucs & ~0x7ff)) { /* 110????? 10?????? */ - *bp++ = 0xc0 | (ucs >> 6); - *bp++ = 0x80 | (ucs & 0x3f); - } - else { /* 1110???? 10?????? 10?????? */ - *bp++ = 0xe0 | (ucs >> 12); - *bp++ = 0x80 | ((ucs >> 6) & 0x3f); - *bp++ = 0x80 | (ucs & 0x3f); - } - /* UTF-8 is defined for words of up to 31 bits, - but we need only 16 bits here */ - } - } else { - /* convert to 8-bit */ - int inv_translate = vc->display_fg->fg_console->vc_translate; - int i; - unsigned char c; - - for (i = 0; i < sel_buffer_lth; i++) { - c = inverse_translate(inv_translate, sel_buffer[i]); - if (c) *bp++ = c; - } - } poke_blanked_console(vc->display_fg); add_wait_queue(&vc->paste_wait, &wait); - p = paste_buffer; - while (bp > p) { + while (sel_buffer && sel_buffer_lth > pasted) { set_current_state(TASK_INTERRUPTIBLE); if (test_bit(TTY_THROTTLED, &tty->flags)) { schedule(); continue; } - count = bp - p; + count = sel_buffer_lth - pasted; count = MIN(count, tty->ldisc.receive_room(tty)); - tty->ldisc.receive_buf(tty, p, 0, count); - p += count; + tty->ldisc.receive_buf(tty, sel_buffer + pasted, 0, count); + pasted += count; } remove_wait_queue(&vc->paste_wait, &wait); set_current_state(TASK_RUNNING); - kfree(paste_buffer); return 0; } Index: tty_io.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/char/tty_io.c,v retrieving revision 1.53 retrieving revision 1.54 diff -u -d -r1.53 -r1.54 --- tty_io.c 30 Oct 2002 17:29:35 -0000 1.53 +++ tty_io.c 1 Nov 2002 23:27:32 -0000 1.54 @@ -2079,15 +2079,7 @@ driver->put_char = tty_default_put_char; list_add(&driver->tty_drivers, &tty_drivers); - - //if (!(driver->flags & TTY_DRIVER_CONSOLE)) - - if (!driver->console) { - driver->tty_lock = kmalloc(sizeof(struct semaphore),GFP_KERNEL); - init_MUTEX(driver->tty_lock); - } else - driver->tty_lock = &driver->console->lock; - + if ( !(driver->flags & TTY_DRIVER_NO_DEVFS) ) { for(i = 0; i < driver->num; i++) tty_register_devfs(driver, 0, driver->minor_start + i); Index: vc_screen.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/char/vc_screen.c,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- vc_screen.c 23 Jan 2002 23:56:41 -0000 1.21 +++ vc_screen.c 1 Nov 2002 23:27:32 -0000 1.22 @@ -31,10 +31,10 @@ #include <linux/interrupt.h> #include <linux/mm.h> #include <linux/init.h> -#include <linux/console.h> #include <linux/vt_kern.h> #include <linux/selection.h> -#include <linux/kbd_kern.h> +#include <linux/console.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/byteorder.h> #include <asm/unaligned.h> @@ -43,9 +43,7 @@ #undef org #undef addr #define HEADER_SIZE 4 -#define CON_BUF_SIZE PAGE_SIZE -/* note the word offset */ unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed) { return screenpos(vc, 2 * w_offset, viewed); @@ -76,29 +74,44 @@ if ((unsigned long)org == vc->vc_pos) { vc->display_fg->cursor_original = -1; add_softcursor(vc); - } + } } -static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) + +static int +vcs_size(struct inode *inode) { - struct vc_data *vc = (struct vc_data *) file->private_data; - struct inode *inode = file->f_dentry->d_inode; + int minor = minor(inode->i_rdev); + int currcons = minor & 127; + struct vc_data *vc; int size; - if (!vc) { - /* Impossible ? */ - if (!vt_cons->fg_console) - return -ENXIO; - vc = vt_cons->fg_console; - } + if (currcons == 0) + currcons = vt_cons->fg_console->vc_num; + else + currcons--; + + vc = vt_cons->vc_cons[currcons]; + + if (!vc) + return -ENXIO; - size = vc->vc_rows * vc->vc_cols; + size = vc->vc_rows * vc->vc_cols; - if (minor(inode->i_rdev) & 128) - size = 2*size + HEADER_SIZE; + if (minor & 128) + size = 2*size + HEADER_SIZE; + return size; +} + +static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) +{ + int size; + lock_kernel(); + size = vcs_size(file->f_dentry->d_inode); switch (orig) { default: + unlock_kernel(); return -EINVAL; case 2: offset += size; @@ -108,41 +121,55 @@ case 0: break; } - if (offset < 0 || offset > size) + if (offset < 0 || offset > size) { + unlock_kernel(); return -EINVAL; + } file->f_pos = offset; + unlock_kernel(); return file->f_pos; } +/* We share this temporary buffer with the console write code + * so that we can easily avoid touching user space while holding the + * console spinlock. + */ +extern char con_buf[PAGE_SIZE]; +#define CON_BUF_SIZE PAGE_SIZE +extern struct semaphore con_buf_sem; + static ssize_t vcs_read(struct file *file, char *buf, size_t count, loff_t *ppos) { - struct vc_data *vc = (struct vc_data *) file->private_data; struct inode *inode = file->f_dentry->d_inode; unsigned int currcons = minor(inode->i_rdev); + struct vc_data *vc; long pos = *ppos; long viewed, attr, read; int col, maxcol; unsigned short *org = NULL; ssize_t ret; - down(&vc->display_fg->lock); + down(&con_buf_sem); /* Select the proper current console and verify * sanity of the situation under the console lock. */ - acquire_console_sem(vc->vc_tty->device); + acquire_console_sem(); attr = (currcons & 128); currcons = (currcons & 127); if (currcons == 0) { - vc = vt_cons->fg_console; + currcons = vt_cons->fg_console->vc_num; viewed = 1; } else { - vc = (struct vc_data *) file->private_data; + currcons--; viewed = 0; } ret = -ENXIO; + + vc = vt_cons->vc_cons[currcons]; + if (!vc) goto unlock_out; @@ -161,10 +188,7 @@ * as copy_to_user at the end of this loop * could sleep. */ - size = vc->vc_rows * vc->vc_cols; - if (minor(inode->i_rdev) & 128) - size = 2*size + HEADER_SIZE; - + size = vcs_size(inode); if (pos >= size) break; if (count > size - pos) @@ -174,12 +198,12 @@ if (this_round > CON_BUF_SIZE) this_round = CON_BUF_SIZE; - /* Perform the whole read into the current VC's con_buf. + /* Perform the whole read into the local con_buf. * Then we can drop the console spinlock and safely * attempt to move it to userspace. */ - con_buf_start = con_buf0 = vc->display_fg->con_buf; + con_buf_start = con_buf0 = con_buf; orig_count = this_round; maxcol = vc->vc_cols; if (!attr) { @@ -216,7 +240,7 @@ /* Advance state pointers and move on. */ this_round -= tmp_count; p = HEADER_SIZE; - con_buf0 = vc->display_fg->con_buf + HEADER_SIZE; + con_buf0 = con_buf + HEADER_SIZE; /* If this_round >= 0, then p is even... */ } else if (p & 1) { /* Skip first byte for output if start address is odd @@ -264,9 +288,9 @@ * the pagefault handling code may want to call printk(). */ - release_console_sem(vc->vc_tty->device); + release_console_sem(); ret = copy_to_user(buf, con_buf_start, orig_count); - acquire_console_sem(vc->vc_tty->device); + acquire_console_sem(); if (ret) { read += (orig_count - ret); @@ -282,17 +306,17 @@ if (read) ret = read; unlock_out: - release_console_sem(vc->vc_tty->device); - up(&vc->display_fg->lock); + release_console_sem(); + up(&con_buf_sem); return ret; } static ssize_t vcs_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { - struct vc_data *vc = (struct vc_data *) file->private_data; struct inode *inode = file->f_dentry->d_inode; unsigned int currcons = minor(inode->i_rdev); + struct vc_data *vc; long pos = *ppos; long viewed, attr, size, written; char *con_buf0; @@ -300,31 +324,31 @@ u16 *org0 = NULL, *org = NULL; size_t ret; - down(&vc->display_fg->lock); + down(&con_buf_sem); /* Select the proper current console and verify * sanity of the situation under the console lock. */ - acquire_console_sem(vc->vc_tty->device); + acquire_console_sem(); attr = (currcons & 128); currcons = (currcons & 127); if (currcons == 0) { - vc = vt_cons->fg_console; + currcons = vt_cons->fg_console->vc_num; viewed = 1; } else { - vc = (struct vc_data *) file->private_data; + currcons--; viewed = 0; } ret = -ENXIO; + + vc = vt_cons->vc_cons[currcons]; + if (!vc) goto unlock_out; - size = vc->vc_rows * vc->vc_cols; - if (minor(inode->i_rdev) & 128) - size = 2*size + HEADER_SIZE; - + size = vcs_size(inode); ret = -EINVAL; if (pos < 0 || pos > size) goto unlock_out; @@ -342,9 +366,9 @@ /* Temporarily drop the console lock so that we can read * in the write data from userspace safely. */ - release_console_sem(vc->vc_tty->device); - ret = copy_from_user(&vc->display_fg->con_buf, buf, this_round); - acquire_console_sem(vc->vc_tty->device); + release_console_sem(); + ret = copy_from_user(con_buf, buf, this_round); + acquire_console_sem(); if (ret) { this_round -= ret; @@ -363,10 +387,7 @@ * the user buffer, so recheck. * Return data written up to now on failure. */ - size = vc->vc_rows * vc->vc_cols; - if (minor(inode->i_rdev) & 128) - size = 2*size + HEADER_SIZE; - + size = vcs_size(inode); if (pos >= size) break; if (this_round > size - pos) @@ -376,7 +397,7 @@ * under the lock using the local kernel buffer. */ - con_buf0 = vc->display_fg->con_buf; + con_buf0 = con_buf; orig_count = this_round; maxcol = vc->vc_cols; p = pos; @@ -389,7 +410,8 @@ unsigned char c = *con_buf0++; this_round--; - vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org); + vcs_scr_writew(vc, + (vcs_scr_readw(vc, org) & 0xff00) | c, org); org++; if (++col == maxcol) { org = screen_pos(vc, p, viewed); @@ -470,24 +492,20 @@ ret = written; unlock_out: - release_console_sem(vc->vc_tty->device); - up(&vc->display_fg->lock); + release_console_sem(); + + up(&con_buf_sem); + return ret; } static int vcs_open(struct inode *inode, struct file *filp) { - unsigned int currcons = (minor(inode->i_rdev) & 127); - struct vc_data *vc; + unsigned int currcons = minor(inode->i_rdev) & 127; - if (currcons) { - vc = find_vc(currcons-1); - if (vc) - filp->private_data = vc; - else - return -ENXIO; - } + if (currcons && !vt_cons->vc_cons[currcons-1]) + return -ENXIO; return 0; } @@ -508,10 +526,10 @@ sprintf (name, "a%u", index + 1); if (unregister) { - devfs_unregister ( devfs_find_handle (devfs_handle, name + 1, 0, 0, - DEVFS_SPECIAL_CHR, 0) ); - devfs_unregister ( devfs_find_handle (devfs_handle, name, 0, 0, - DEVFS_SPECIAL_CHR, 0) ); + devfs_find_and_unregister(devfs_handle, name + 1, 0, 0, + DEVFS_SPECIAL_CHR, 0); + devfs_find_and_unregister(devfs_handle, name, 0, 0, + DEVFS_SPECIAL_CHR, 0); } else { @@ -529,7 +547,7 @@ { int error; - error = devfs_register_chrdev(VCS_MAJOR, "vcs", &vcs_fops); + error = register_chrdev(VCS_MAJOR, "vcs", &vcs_fops); if (error) printk("unable to get major %d for vcs device", VCS_MAJOR); Index: vt.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/char/vt.c,v retrieving revision 1.122 retrieving revision 1.123 diff -u -d -r1.122 -r1.123 --- vt.c 27 Jul 2002 19:33:27 -0000 1.122 +++ vt.c 1 Nov 2002 23:27:32 -0000 1.123 @@ -1,11 +1,77 @@ /* - * vt.c - Built-in console device - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 1999, 2000 Dominik Kubla + * linux/drivers/char/vt.c * - * $Id$ + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* [...2361 lines suppressed...] + vc->vc_can_do_color ? "colour" : "mono", + desc, vc->vc_cols, vc->vc_rows); } /* - * Visible symbols for modules + * Visible symbols for modules */ EXPORT_SYMBOL(color_table); EXPORT_SYMBOL(default_red); EXPORT_SYMBOL(default_grn); EXPORT_SYMBOL(default_blu); -EXPORT_SYMBOL(vt_map_display); -EXPORT_SYMBOL(release_vt); EXPORT_SYMBOL(vc_resize); -EXPORT_SYMBOL(vc_init); EXPORT_SYMBOL(console_blank_hook); +EXPORT_SYMBOL(vt_cons); EXPORT_SYMBOL(take_over_console); Index: vt_ioctl.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/char/vt_ioctl.c,v retrieving revision 1.69 retrieving revision 1.70 diff -u -d -r1.69 -r1.70 --- vt_ioctl.c 2 Aug 2002 14:58:50 -0000 1.69 +++ vt_ioctl.c 1 Nov 2002 23:27:32 -0000 1.70 @@ -2,15 +2,13 @@ * linux/drivers/char/vt_ioctl.c * * Copyright (C) 1992 obz under the linux copyright - * Copyright (C) 2002 James Simmons <jsi...@us...> + * 2002 James Simmons <jsi...@us...> * * Dynamic diacritical handling - ae...@cw... - Dec 1993 * Dynamic keymap and string allocation - ae...@cw... - May 1994 * Restrict VT switching via ioctl() - gr...@cs... - Dec 1995 * Some code moved for less code duplication - Andi Kleen - Mar 1997 * Check put/get_user, cleanups - ac...@co... - Jun 2001 [...1976 lines suppressed...] - * server dies and the screen remains blanked due to - * KD_GRAPHICS! It would be nice to do this outside of - * VT_PROCESS but there is no single process to account - * and tracking tty count may be undesirable. - */ - if (old_vc_mode != new_vc->vc_mode) { - if (new_vc->vc_mode == KD_TEXT) - unblank_screen(new_vc->display_fg); - else - do_blank_screen(new_vc); - } - } - } - - /* - * Wake anyone waiting for their VT to activate - */ - wake_up(&vt_activate_queue); - return; -} |