From: Aivils S. <Aiv...@un...> - 2003-09-12 09:09:18
|
Hi, all! Updates may reach public CVS 13-SEP-2003 11:00GMT. multiple current tty, variable count of VC per VT, fix screenbuf kmalloced, dummy console configurable, fix dead code. redundant consoles will be ignored. BROKEN: MDA console, fb_con. Power management of console lead oops - commented out. UNKNOWN: PC mainboard speaker and keyboard beeper. TODO: dummy console command line parser to set up VC per VT. /proc interface to manage console-input link (i use it). xf86 /proc filter in the kernel to allow newbies start ruby for X. If James agree, then made snapshot for 2.6.0 release available into sf.net download. FILE: diff -Nurp ruby-CVS/drivers/char/console_macros.h ruby-2.6.0-test3/drivers/char/console_macros.h --- ruby-CVS/drivers/char/console_macros.h 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/drivers/char/console_macros.h 2003-09-11 13:44:36.000000000 +0100 @@ -43,6 +43,7 @@ #define decim (vc->vc_decim) #define deccolm (vc->vc_deccolm) #define need_wrap (vc->vc_need_wrap) +#define kmalloced (vc->vc_kmalloced) #define report_mouse (vc->vc_report_mouse) #define color (vc->vc_color) #define s_color (vc->vc_s_color) diff -Nurp ruby-CVS/drivers/char/consolemap.c ruby-2.6.0-test3/drivers/char/consolemap.c --- ruby-CVS/drivers/char/consolemap.c 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/drivers/char/consolemap.c 2003-09-11 13:44:36.000000000 +0100 @@ -234,7 +234,7 @@ static void update_user_maps(struct vc_d struct uni_pagedir *p, *q = NULL; int i; - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { + for (i = 0; i < vc->display_fg->vc_count; i++) { struct vc_data *tmp = vc->display_fg->vc_cons[i]; if (!tmp) @@ -379,7 +379,7 @@ static int con_unify_unimap(struct vc_da struct uni_pagedir *q; int i, j, k; - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { + for (i = 0; i < vc->display_fg->vc_count; i++) { struct vc_data *tmp = vc->display_fg->vc_cons[i]; if (!tmp) @@ -670,7 +670,7 @@ console_map_init(void) struct vt_struct *vt = vt_cons; int i; - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { + for (i = 0; i < vt->vc_count; i++) { struct vc_data *vc = vt->vc_cons[i]; if (vc && !*vc->vc_uni_pagedir_loc) diff -Nurp ruby-CVS/drivers/char/decvte.c ruby-2.6.0-test3/drivers/char/decvte.c --- ruby-CVS/drivers/char/decvte.c 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/drivers/char/decvte.c 2003-09-11 13:44:36.000000000 +0100 @@ -513,10 +513,10 @@ static void set_mode(struct vc_data *vc, switch (par[i]) { case 1: /* DECCKM - Cursor keys mode */ if (on_off) - set_kbd_mode(vc->kbd_table, + set_kbd_mode(&vc->kbd_table, VC_CKMODE); else - clr_kbd_mode(vc->kbd_table, + clr_kbd_mode(&vc->kbd_table, VC_CKMODE); break; case 2: /* DECANM - ANSI mode */ @@ -550,10 +550,10 @@ static void set_mode(struct vc_data *vc, case 8: /* DECARM - Autorepeat mode */ decarm = on_off; if (on_off) - set_kbd_mode(vc->kbd_table, + set_kbd_mode(&vc->kbd_table, VC_REPEAT); else - clr_kbd_mode(vc->kbd_table, + clr_kbd_mode(&vc->kbd_table, VC_REPEAT); break; case 9: @@ -573,10 +573,10 @@ static void set_mode(struct vc_data *vc, case 66: /* DECNKM - Numeric keybad mode */ decnkm = on_off; if (on_off) - set_kbd_mode(vc->kbd_table, + set_kbd_mode(&vc->kbd_table, VC_APPLIC); else - clr_kbd_mode(vc->kbd_table, + clr_kbd_mode(&vc->kbd_table, VC_APPLIC); break; case 67: /* DECBKM - Backarrow key mode */ @@ -603,10 +603,10 @@ static void set_mode(struct vc_data *vc, break; case 20: /* Lf, Enter == CrLf/Lf */ if (on_off) - set_kbd_mode(vc->kbd_table, + set_kbd_mode(&vc->kbd_table, VC_CRLF); else - clr_kbd_mode(vc->kbd_table, + clr_kbd_mode(&vc->kbd_table, VC_CRLF); break; } @@ -1008,10 +1008,10 @@ void vte_ris(struct vc_data *vc, int do_ irm = 0; /* replace */ lnm = 0; /* line feed */ - set_kbd_mode(vc->kbd_table, VC_REPEAT); - clr_kbd_mode(vc->kbd_table, VC_CKMODE); - clr_kbd_mode(vc->kbd_table, VC_APPLIC); - clr_kbd_mode(vc->kbd_table, VC_CRLF); + set_kbd_mode(&vc->kbd_table, VC_REPEAT); + clr_kbd_mode(&vc->kbd_table, VC_CKMODE); + clr_kbd_mode(&vc->kbd_table, VC_APPLIC); + clr_kbd_mode(&vc->kbd_table, VC_CRLF); vc->kbd_table.lockstate = KBD_DEFLOCK; vc->kbd_table.slockstate = 0; vc->kbd_table.ledmode = LED_SHOW_FLAGS; @@ -1131,7 +1131,7 @@ void terminal_emulation(struct tty_struc * DEC VT series processes FF as LF. */ vte_lf(vc); - if (!get_kbd_mode(vc->kbd_table, VC_CRLF)) + if (!get_kbd_mode(&vc->kbd_table, VC_CRLF)) return; case 0x0d: /* CR - Carriage return */ vte_cr(vc); @@ -1305,11 +1305,11 @@ void terminal_emulation(struct tty_struc return; case '=': /* DECKPAM - Keypad application mode */ decnkm = 1; - set_kbd_mode(vc->kbd_table, VC_APPLIC); + set_kbd_mode(&vc->kbd_table, VC_APPLIC); return; case '>': /* DECKPNM - Keypad numeric mode */ decnkm = 0; - clr_kbd_mode(vc->kbd_table, VC_APPLIC); + clr_kbd_mode(&vc->kbd_table, VC_APPLIC); return; /* ===== C1 control functions ===== */ diff -Nurp ruby-CVS/drivers/char/keyboard.c ruby-2.6.0-test3/drivers/char/keyboard.c --- ruby-CVS/drivers/char/keyboard.c 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/drivers/char/keyboard.c 2003-09-11 13:44:36.000000000 +0100 @@ -365,7 +365,7 @@ static void fn_enter(struct vc_data *vc) diacr = 0; } put_queue(vc, 13); - if (get_kbd_mode(vc->kbd_table, VC_CRLF)) + if (get_kbd_mode(&vc->kbd_table, VC_CRLF)) put_queue(vc, 10); } @@ -373,14 +373,14 @@ static void fn_caps_toggle(struct vc_dat { if (rep) return; - chg_kbd_led(vc->kbd_table, VC_CAPSLOCK); + chg_kbd_led(&vc->kbd_table, VC_CAPSLOCK); } static void fn_caps_on(struct vc_data *vc) { if (rep) return; - set_kbd_led(vc->kbd_table, VC_CAPSLOCK); + set_kbd_led(&vc->kbd_table, VC_CAPSLOCK); } static void fn_show_ptregs(struct vc_data *vc) @@ -412,7 +412,7 @@ static void fn_hold(struct vc_data *vc) static void fn_num(struct vc_data *vc) { - if (get_kbd_mode(vc->kbd_table, VC_APPLIC)) + if (get_kbd_mode(&vc->kbd_table, VC_APPLIC)) applkey(vc, 'P', 1); else fn_bare_num(vc); @@ -427,7 +427,7 @@ static void fn_num(struct vc_data *vc) static void fn_bare_num(struct vc_data *vc) { if (!rep) - chg_kbd_led(vc->kbd_table, VC_NUMLOCK); + chg_kbd_led(&vc->kbd_table, VC_NUMLOCK); } static void fn_lastcons(struct vc_data *vc) @@ -444,12 +444,12 @@ static void fn_dec_console(struct vc_dat for (i = j-1; i != j; i--) { if (i == -1) - i = MAX_NR_USER_CONSOLES-1; + i = vt->vc_count - 1; tmp = vt->vc_cons[i]; if (tmp) break; } - set_console(tmp); + if(tmp) set_console(tmp); } static void fn_inc_console(struct vc_data *vc) @@ -459,13 +459,13 @@ static void fn_inc_console(struct vc_dat struct vc_data *tmp = NULL; for (i = j+1; i != j; i++) { - if (i == MAX_NR_USER_CONSOLES) + if (i == vt->vc_count) i = 0; tmp = vt->vc_cons[i]; if (tmp) break; } - set_console(tmp); + if(tmp) set_console(tmp); } static void fn_send_intr(struct vc_data *vc) @@ -622,7 +622,7 @@ static void k_cur(struct vc_data *vc, un if (up_flag) return; - applkey(vc, cur_chars[value], get_kbd_mode(vc->kbd_table, VC_CKMODE)); + applkey(vc, cur_chars[value], get_kbd_mode(&vc->kbd_table, VC_CKMODE)); } static void k_pad(struct vc_data *vc, unsigned char value, char up_flag) @@ -634,12 +634,12 @@ static void k_pad(struct vc_data *vc, un return; /* no action, if this is a key release */ /* kludge... shift forces cursor/number keys */ - if (get_kbd_mode(vc->kbd_table, VC_APPLIC) && !shift_down[KG_SHIFT]) { + if (get_kbd_mode(&vc->kbd_table, VC_APPLIC) && !shift_down[KG_SHIFT]) { applkey(vc, app_map[value], 1); return; } - if (!get_kbd_led(vc->kbd_table, VC_NUMLOCK)) + if (!get_kbd_led(&vc->kbd_table, VC_NUMLOCK)) switch (value) { case KVAL(K_PCOMMA): case KVAL(K_PDOT): @@ -673,12 +673,12 @@ static void k_pad(struct vc_data *vc, un k_fn(vc, KVAL(K_PGUP), 0); return; case KVAL(K_P5): - applkey(vc, 'G', get_kbd_mode(vc->kbd_table, VC_APPLIC)); + applkey(vc, 'G', get_kbd_mode(&vc->kbd_table, VC_APPLIC)); return; } put_queue(vc, pad_chars[value]); - if (value == KVAL(K_PENTER) && get_kbd_mode(vc->kbd_table, VC_CRLF)) + if (value == KVAL(K_PENTER) && get_kbd_mode(&vc->kbd_table, VC_CRLF)) put_queue(vc, 10); } @@ -695,7 +695,7 @@ static void k_shift(struct vc_data *vc, if (value == KVAL(K_CAPSSHIFT)) { value = KVAL(K_SHIFT); if (!up_flag) - clr_kbd_led(vc->kbd_table, VC_CAPSLOCK); + clr_kbd_led(&vc->kbd_table, VC_CAPSLOCK); } if (up_flag) { @@ -728,7 +728,7 @@ static void k_meta(struct vc_data *vc, u if (up_flag) return; - if (get_kbd_mode(vc->kbd_table, VC_META)) { + if (get_kbd_mode(&vc->kbd_table, VC_META)) { put_queue(vc, '\033'); put_queue(vc, value); } else @@ -761,7 +761,7 @@ static void k_lock(struct vc_data *vc, u { if (up_flag || rep) return; - chg_kbd_lock(vc->kbd_table, value); + chg_kbd_lock(&vc->kbd_table, value); } static void k_slock(struct vc_data *vc, unsigned char value, char up_flag) @@ -769,11 +769,11 @@ static void k_slock(struct vc_data *vc, k_shift(vc, value, up_flag); if (up_flag || rep) return; - chg_kbd_slock(vc->kbd_table, value); + chg_kbd_slock(&vc->kbd_table, value); /* try to make Alt, oops, AltGr and such work */ if (!key_maps[vc->kbd_table.lockstate ^ vc->kbd_table.slockstate]) { vc->kbd_table.slockstate = 0; - chg_kbd_slock(vc->kbd_table, value); + chg_kbd_slock(&vc->kbd_table, value); } } @@ -1046,7 +1046,7 @@ void kbd_keycode(struct vt_struct *vt, u else clear_bit(keycode, key_down); - if (rep && (!get_kbd_mode(vc->kbd_table, VC_REPEAT) || (tty && + if (rep && (!get_kbd_mode(&vc->kbd_table, VC_REPEAT) || (tty && (!L_ECHO(tty) && tty->driver->chars_in_buffer(tty))))) { /* * Don't repeat a key if the input buffers are not empty and the @@ -1080,7 +1080,7 @@ void kbd_keycode(struct vt_struct *vt, u if (type == KT_LETTER) { type = KT_LATIN; - if (get_kbd_led(vc->kbd_table, VC_CAPSLOCK)) { + if (get_kbd_led(&vc->kbd_table, VC_CAPSLOCK)) { key_map = key_maps[shift_final ^ (1 << KG_SHIFT)]; if (key_map) keysym = key_map[keycode]; @@ -1145,11 +1145,24 @@ static struct input_handle *kbd_connect( * beeper is independent we can share it with all VTs that don't * have one. */ + //if(strncmp(dev->phys,"isa0061",7)) if (i != BTN_MISC) { - if (!vt->keyboard) { - vt->keyboard = handle; - handle->private = vt; - } + while (vt) { + if (vt->next && !vt->next->keyboard) { + vt = vt->next; + continue; + } + if (!vt->keyboard) { + vt->keyboard = handle; + handle->private = vt; + printk(KERN_INFO "keyboard.c: %s vc:%d-%d\n", + dev->name, + vt->first_vc, + vt->first_vc + vt->vc_count - 1); + break; + } + vt = vt->next; + } kbd_refresh_leds(handle); } if (test_bit(EV_SND, dev->evbit)) { diff -Nurp ruby-CVS/drivers/char/selection.c ruby-2.6.0-test3/drivers/char/selection.c --- ruby-CVS/drivers/char/selection.c 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/drivers/char/selection.c 2003-09-11 13:44:36.000000000 +0100 @@ -46,7 +46,7 @@ static char *sel_buffer; /* set reverse video on characters s-e of console with selection. */ inline static void highlight(const int s, const int e) { - invert_screen(vt_cons->vc_cons[sel_cons], s, e-s+2, 1); + invert_screen(find_vc(sel_cons), s, e-s+2, 1); } u16 screen_glyph(struct vc_data *vc, int offset) @@ -63,12 +63,12 @@ u16 screen_glyph(struct vc_data *vc, int /* use complementary color to show the pointer */ inline static void highlight_pointer(const int where) { - complement_pos(vt_cons->vc_cons[sel_cons], where); + complement_pos(find_vc(sel_cons), where); } static unsigned char sel_pos(int n) { - return inverse_translate(vt_cons->vc_cons[sel_cons], screen_glyph(vt_cons->vc_cons[sel_cons], n)); + return inverse_translate(find_vc(sel_cons), screen_glyph(find_vc(sel_cons), n)); } /* diff -Nurp ruby-CVS/drivers/char/vc_screen.c ruby-2.6.0-test3/drivers/char/vc_screen.c --- ruby-CVS/drivers/char/vc_screen.c 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/drivers/char/vc_screen.c 2003-09-11 13:44:36.000000000 +0100 @@ -129,7 +129,7 @@ static loff_t vcs_lseek(struct file *fil * so that we can easily avoid touching user space while holding the * console spinlock. */ -extern char con_buf[PAGE_SIZE]; +//extern char con_buf[PAGE_SIZE]; #define CON_BUF_SIZE PAGE_SIZE extern struct semaphore con_buf_sem; @@ -196,7 +196,7 @@ vcs_read(struct file *file, char *buf, s * attempt to move it to userspace. */ - con_buf_start = con_buf0 = con_buf; + con_buf_start = con_buf0 = vc->display_fg->con_buf; orig_count = this_round; maxcol = vc->vc_cols; if (!attr) { @@ -233,7 +233,7 @@ vcs_read(struct file *file, char *buf, s /* Advance state pointers and move on. */ this_round -= tmp_count; p = HEADER_SIZE; - con_buf0 = con_buf + HEADER_SIZE; + con_buf0 = vc->display_fg->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 @@ -358,7 +358,7 @@ vcs_write(struct file *file, const char * in the write data from userspace safely. */ release_console_sem(); - ret = copy_from_user(con_buf, buf, this_round); + ret = copy_from_user(vc->display_fg->con_buf, buf, this_round); acquire_console_sem(); if (ret) { @@ -388,7 +388,7 @@ vcs_write(struct file *file, const char * under the lock using the local kernel buffer. */ - con_buf0 = con_buf; + con_buf0 = vc->display_fg->con_buf; orig_count = this_round; maxcol = vc->vc_cols; p = pos; diff -Nurp ruby-CVS/drivers/char/vt.c ruby-2.6.0-test3/drivers/char/vt.c --- ruby-CVS/drivers/char/vt.c 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/drivers/char/vt.c 2003-09-11 13:44:36.000000000 +0100 @@ -122,6 +122,9 @@ extern void console_map_init(void); #ifdef CONFIG_VGA_CONSOLE extern int vga_console_init(void); #endif +#ifdef CONFIG_DUMMY_CONSOLE +extern int dumb_console_init(void); +#endif #if defined (CONFIG_PROM_CONSOLE) extern void prom_con_init(void); #endif @@ -179,7 +182,6 @@ int (*console_blank_hook)(int); #endif static int pm_con_request(struct pm_dev *dev, pm_request_t rqst, void *data); -static struct pm_dev *pm_con; /* * Console cursor handling @@ -685,6 +687,7 @@ static void powerdown_screen(unsigned lo struct vt_struct *vt = (struct vt_struct *) private; struct vc_data *vc = vt->fg_console; + vc->display_fg->timer.data = (long) vt; vc->display_fg->timer.function = unblank_screen_t; switch (vc->display_fg->blank_mode) { case VESA_NO_BLANKING: @@ -697,9 +700,9 @@ static void powerdown_screen(unsigned lo } } -static void timer_do_blank_screen(int entering_gfx, int from_timer_handler) +static void timer_do_blank_screen(struct vt_struct *vt, int entering_gfx, int from_timer_handler) { - struct vc_data *vc = vt_cons->fg_console; + struct vc_data *vc = vt->fg_console; int i; if (vc->display_fg->vt_blanked) @@ -724,6 +727,7 @@ static void timer_do_blank_screen(int en hide_cursor(vc); if (!from_timer_handler) del_timer_sync(&vc->display_fg->timer); + vc->display_fg->timer.data = (long) vc->display_fg; vc->display_fg->timer.function = unblank_screen_t; save_screen(vc); @@ -736,6 +740,7 @@ static void timer_do_blank_screen(int en if (console_blank_hook && console_blank_hook(1)) return; if (vc->display_fg->off_interval) { + vc->display_fg->timer.data = (long) vc->display_fg; vc->display_fg->timer.function = powerdown_screen; mod_timer(&vc->display_fg->timer, jiffies + vc->display_fg->off_interval); } @@ -743,9 +748,9 @@ static void timer_do_blank_screen(int en sw->con_blank(vc, vc->display_fg->blank_mode + 1); } -void do_blank_screen(int entering_gfx) +void do_blank_screen(struct vt_struct *vt, int entering_gfx) { - timer_do_blank_screen(entering_gfx, 0); + timer_do_blank_screen(vt, entering_gfx, 0); } /* @@ -753,7 +758,7 @@ void do_blank_screen(int entering_gfx) */ static void unblank_screen_t(unsigned long dummy) { - unblank_screen(); + unblank_vt((struct vt_struct *) dummy); } /* @@ -761,15 +766,15 @@ static void unblank_screen_t(unsigned lo */ static void blank_screen(unsigned long dummy) { - timer_do_blank_screen(0, 1); + timer_do_blank_screen((struct vt_struct *) dummy, 0, 1); } /* - * Called by timer as well as from vt_console_driver + * Called by timer */ -void unblank_screen(void) +void unblank_vt(struct vt_struct *vt) { - struct vc_data *vc = vt_cons->fg_console; + struct vc_data *vc = vt->fg_console; ignore_poke = 0; if (!vc->display_fg->vt_blanked) @@ -782,6 +787,7 @@ void unblank_screen(void) if (vcmode != KD_TEXT) return; /* but leave vc->vc_display_fg->vt_blanked != 0 */ + vc->display_fg->timer.data = (long) vt; vc->display_fg->timer.function = blank_screen; if (vc->display_fg->blank_interval) { mod_timer(&vc->display_fg->timer, jiffies + vc->display_fg->blank_interval); @@ -797,6 +803,19 @@ void unblank_screen(void) set_cursor(vc); } +/* + * Called from vt_console_driver + */ +void unblank_screen(void) +{ + struct vt_struct *vt = vt_cons; + + while(vt) { + unblank_vt(vt); + vt = vt->next; + } +} + void poke_blanked_console(struct vt_struct *vt) { struct vc_data *vc = vt->fg_console; @@ -816,16 +835,20 @@ void poke_blanked_console(struct vt_stru */ static int pm_con_request(struct pm_dev *dev, pm_request_t rqst, void *data) { - switch (rqst) - { - case PM_RESUME: - unblank_screen(); - break; - case PM_SUSPEND: - do_blank_screen(0); - break; - } - return 0; + struct vt_struct *vt = vt_cons; /*FIXME*/ + + if (vt) { + switch (rqst) + { + case PM_RESUME: + unblank_vt(vt); + break; + case PM_SUSPEND: + do_blank_screen(vt, 0); + break; + } + } + return 0; } /* * This is the console switching callback. @@ -887,6 +910,7 @@ static void visual_init(struct vc_data * can_do_color = default_mode->vc_can_do_color; video_num_columns = default_mode->vc_cols; video_num_lines = default_mode->vc_rows; + video_scan_lines = default_mode->vc_scan_lines; screensize = video_num_columns * video_num_lines; vc->vc_font = vc->display_fg->default_mode->vc_font; sw->con_init(vc, init); @@ -911,9 +935,14 @@ static void vc_init(struct vc_data *vc, struct vc_data *find_vc(int currcons) { - struct vt_struct *vt = vt_cons; + struct vt_struct *vt; - return vt->vc_cons[currcons - vt->first_vc]; + for (vt = vt_cons; vt != NULL; vt = vt->next) { + if ((currcons < vt->first_vc + vt->vc_count) && + currcons >= vt->first_vc) + return vt->vc_cons[currcons - vt->first_vc]; + } + return NULL; } struct vc_data *vc_allocate(unsigned int currcons) @@ -927,18 +956,26 @@ struct vc_data *vc_allocate(unsigned int } /* prevent users from taking too much memory */ - if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE)) { + if (currcons >= MAX_NR_CONSOLES && !capable(CAP_SYS_RESOURCE)) { currcons = -EPERM; return NULL; } + for (vt = vt_cons; vt != NULL; vt = vt->next) { + if (currcons < vt->first_vc + vt->vc_count && + currcons >= vt->first_vc) + goto found_pool; + } + currcons = -ENXIO; + return NULL; + found_pool: /* due to the granularity of kmalloc, we waste some memory here */ /* the alloc is done in two steps, to optimize the common situation of a 25x80 console (structsize=216, screenbuf_size=4000) */ /* although the numbers above are not valid since long ago, the point is still up-to-date and the comment still has its value even if only as a historical artifact. --mj, July 1998 */ - if (vt->kmalloced || !((vt->first_vc + 1)== currcons)) + if (vt->vt_kmalloced || !((vt->first_vc + 1)== currcons)) vc = (struct vc_data *) kmalloc(sizeof(struct vc_data), GFP_KERNEL); else vc = (struct vc_data *) alloc_bootmem(sizeof(struct vc_data)); @@ -949,15 +986,16 @@ struct vc_data *vc_allocate(unsigned int memset(vc, 0, sizeof(struct vc_data)); cons_num = currcons; - vc->display_fg = vt_cons; + vc->display_fg = vt; visual_init(vc, 1); - if (vt->kmalloced || !((vt->first_vc + 1) == currcons)) { + if (vt->vt_kmalloced || !((vt->first_vc + 1) == currcons)) { screenbuf = (unsigned short *) kmalloc(screenbuf_size, GFP_KERNEL); if (!screenbuf) { kfree(vc); currcons = -ENOMEM; return NULL; } + kmalloced = 1; if (!*vc->vc_uni_pagedir_loc) con_set_default_unimap(vc); } else { @@ -972,6 +1010,11 @@ struct vc_data *vc_allocate(unsigned int if ((vt->first_vc + 1) == currcons) vt->want_vc = vt->fg_console = vt->last_console = vc; vc_init(vc, 1); +/* if (!vt->pm_con) { */ +/* vt->pm_con = pm_register(PM_SYS_DEV, */ +/* PM_SYS_VGA, */ +/* pm_con_request); */ +/* } */ return vc; } @@ -983,13 +1026,9 @@ int vc_disallocate(struct vc_data *vc) if (vc) { sw->con_deinit(vc); vt->vc_cons[cons_num - vt->first_vc] = NULL; - if (vt->kmalloced || !(vt->first_vc == cons_num)) { + if (kmalloced) kfree(screenbuf); - kfree(vc); - } else { - free_bootmem((unsigned long) screenbuf, screenbuf_size); - free_bootmem((unsigned long) vc, sizeof(struct vc_data)); - } + kfree(vc); } release_console_sem(); return 0; @@ -1073,10 +1112,11 @@ int vc_resize(struct vc_data *vc, unsign } if (nlend > nl) scr_memsetw((void *) nl, video_erase_char, nlend - nl); - if (vc->display_fg->kmalloced) + if (kmalloced) { kfree(screenbuf); + } screenbuf = newscreen; - vc->display_fg->kmalloced = 1; + kmalloced = 1; screenbuf_size = ss; set_origin(vc); @@ -1131,7 +1171,7 @@ int mouse_reporting(struct vc_data *vc) * since console_init (and thus con_init) are called before any * kernel memory allocation is available. */ -char con_buf[PAGE_SIZE]; +//char con_buf[PAGE_SIZE]; #define CON_BUF_SIZE PAGE_SIZE DECLARE_MUTEX(con_buf_sem); @@ -1171,12 +1211,12 @@ again: if (count > CON_BUF_SIZE) count = CON_BUF_SIZE; console_conditional_schedule(); - if (copy_from_user(con_buf, buf, count)) { + if (copy_from_user(&vc->display_fg->con_buf, buf, count)) { n = 0; /* ?? are error codes legal here ?? */ goto out; } - buf = con_buf; + buf = vc->display_fg->con_buf; } /* At this point 'buf' is guaranteed to be a kernel buffer @@ -1374,9 +1414,10 @@ static void vt_close(struct tty_struct * static int vt_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count) { + struct vc_data *vc = (struct vc_data *) tty->driver_data; int retval; - pm_access(pm_con); + pm_access(vc->display_fg->pm_con); retval = do_con_write(tty, from_user, buf, count); vt_flush_chars(tty); @@ -1385,9 +1426,11 @@ static int vt_write(struct tty_struct * static void vt_put_char(struct tty_struct *tty, unsigned char ch) { + struct vc_data *vc = (struct vc_data *) tty->driver_data; + if (in_interrupt()) return; /* n_r3964 calls put_char() from interrupt context */ - pm_access(pm_con); + pm_access(vc->display_fg->pm_con); do_con_write(tty, 0, &ch, 1); } @@ -1400,18 +1443,18 @@ static int vt_write_room(struct tty_stru static void vt_flush_chars(struct tty_struct *tty) { - struct vc_data *vc; + struct vc_data *vc = (struct vc_data *) tty->driver_data; if (in_interrupt()) /* from flush_to_ldisc */ return; - pm_access(pm_con); + if(!vc) return; + + pm_access(vc->display_fg->pm_con); /* if we race with vt_close(), vc may be null */ acquire_console_sem(); - vc = (struct vc_data *)tty->driver_data; - if (vc) - set_cursor(vc); + set_cursor(vc); release_console_sem(); } @@ -1433,7 +1476,7 @@ static void vt_stop(struct tty_struct *t vc = (struct vc_data *)tty->driver_data; if (!vc) return; - set_kbd_led(vc->kbd_table, VC_SCROLLOCK); + set_kbd_led(&vc->kbd_table, VC_SCROLLOCK); set_leds(); } @@ -1450,7 +1493,7 @@ static void vt_start(struct tty_struct * if (!vc) return; - clr_kbd_led(vc->kbd_table, VC_SCROLLOCK); + clr_kbd_led(&vc->kbd_table, VC_SCROLLOCK); set_leds(); } @@ -1492,8 +1535,10 @@ void vt_console_print(struct console *co if (!vc) vc = admin_vt->fg_console; + if (!vc) + goto quit; - pm_access(pm_con); + pm_access(vc->display_fg->pm_con); /* read `x' only after setting currcons properly (otherwise the `x' macro will read the x of the foreground console). */ @@ -1664,7 +1709,7 @@ int tioclinux(struct tty_struct *tty, un break; case TIOCL_BLANKSCREEN: /* until explicitly unblanked, not only poked */ ignore_poke = 1; - do_blank_screen(0); + do_blank_screen(vc->display_fg, 0); break; case TIOCL_BLANKEDSCREEN: ret = vc->display_fg->vt_blanked; @@ -1679,16 +1724,21 @@ int tioclinux(struct tty_struct *tty, un /* * Mapping and unmapping displays to a VT */ -const char *vt_map_display(struct vt_struct *vt, int init) +const char *vt_map_display(struct vt_struct *vt, int init, int vc_count) { - const char *display_desc = vt->vt_sw->con_startup(vt, init); + const char *display_desc; + if (current_vc + vc_count > MAX_NR_CONSOLES + 1) + return NULL; + + display_desc = vt->vt_sw->con_startup(vt, init); if (!display_desc) return NULL; /* Now to setup VT */ init_MUTEX(&vt->lock); vt->first_vc = current_vc; + vt->vc_count = vc_count; vt->next = vt_cons; vt_cons = vt; vt->vt_dont_switch = 0; @@ -1716,6 +1766,7 @@ const char *vt_map_display(struct vt_str gotoxy(vt->fg_console, vt->fg_console->vc_x, vt->fg_console->vc_y); vte_ed(vt->fg_console, 0); update_screen(vt->fg_console); + current_vc += vc_count; return display_desc; } @@ -1737,8 +1788,10 @@ static int __init vt_console_init(void) { int err = 0; -#ifdef CONFIG_VGA_CONSOLE +#if defined (CONFIG_VGA_CONSOLE) err = vga_console_init(); +#elif defined (CONFIG_DUMMY_CONSOLE) + err = dumbcon_init(); #endif return err; } @@ -1787,6 +1840,9 @@ int __init vty_init(void) #if defined (CONFIG_FRAMEBUFFER_CONSOLE) fb_console_init(); #endif +#if defined (CONFIG_DUMMY_CONSOLE) + dumb_console_init(); +#endif kbd_init(); console_map_init(); vcs_init(); @@ -1808,7 +1864,7 @@ void take_over_console(struct vt_struct /* First shutdown old console driver */ hide_cursor(vc); - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { + for (i = 0; i < vt->vc_count; i++) { vc = vt->vc_cons[i]; if (vc) sw->con_deinit(vc); @@ -1824,7 +1880,7 @@ void take_over_console(struct vt_struct vt->vt_sw = csw; /* Set the VC states to the new default mode */ - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { + for (i = 0; i < vt->vc_count; i++) { int old_was_color; vc = vt->vc_cons[i]; diff -Nurp ruby-CVS/drivers/char/vt_ioctl.c ruby-2.6.0-test3/drivers/char/vt_ioctl.c --- ruby-CVS/drivers/char/vt_ioctl.c 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/drivers/char/vt_ioctl.c 2003-09-11 13:44:36.000000000 +0100 @@ -497,7 +497,7 @@ int con_set_cmap(struct vc_data *vc, uns get_user(green[i], arg++); get_user(blue[i], arg++); } - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { + for (i = 0; i < vc->display_fg->vc_count; i++) { struct vc_data *tmp = vc->display_fg->vc_cons[i]; if (tmp) { @@ -642,9 +642,9 @@ void complete_change_console(struct vc_d */ if (old_vc_mode != new_vc->vc_mode) { if (new_vc->vc_mode == KD_TEXT) - unblank_screen(); + unblank_vt(new_vc->display_fg); else - do_blank_screen(1); + do_blank_screen(new_vc->display_fg, 1); } /* @@ -673,9 +673,9 @@ void complete_change_console(struct vc_d if (old_vc_mode != new_vc->vc_mode) { if (new_vc->vc_mode == KD_TEXT) - unblank_screen(); + unblank_vt(new_vc->display_fg); else - do_blank_screen(1); + do_blank_screen(new_vc->display_fg, 1); } } } @@ -815,9 +815,9 @@ int vt_ioctl(struct tty_struct *tty, str * explicitly blank/unblank the screen if switching modes */ if (arg == KD_TEXT) - unblank_screen(); + unblank_vt(vc->display_fg); else - do_blank_screen(1); + do_blank_screen(vc->display_fg, 1); return 0; case KDGETMODE: @@ -869,10 +869,10 @@ int vt_ioctl(struct tty_struct *tty, str case KDSKBMETA: switch(arg) { case K_METABIT: - clr_kbd_mode(vc->kbd_table, VC_META); + clr_kbd_mode(&vc->kbd_table, VC_META); break; case K_ESCPREFIX: - set_kbd_mode(vc->kbd_table, VC_META); + set_kbd_mode(&vc->kbd_table, VC_META); break; default: return -EINVAL; @@ -880,7 +880,7 @@ int vt_ioctl(struct tty_struct *tty, str return 0; case KDGKBMETA: - ucval = (get_kbd_mode(vc->kbd_table, VC_META) ? K_ESCPREFIX : K_METABIT); + ucval = (get_kbd_mode(&vc->kbd_table, VC_META) ? K_ESCPREFIX : K_METABIT); setint: return put_user(ucval, (int *)arg); @@ -1027,13 +1027,13 @@ int vt_ioctl(struct tty_struct *tty, str { int j = vc->display_fg->first_vc; - for (i = 0; i < MAX_NR_USER_CONSOLES; ++i, j++) { + for ((j) ? (i = 0) : (i = j = 1); i < vc->display_fg->vc_count; ++i, j++) { struct vc_data *tmp = find_vc(j); if (!tmp || (tmp && !VT_IS_IN_USE(tmp))) break; } - ucval = i < MAX_NR_USER_CONSOLES ? (j) : -1; + ucval = i < vc->display_fg->vc_count ? (j) : -1; goto setint; } /* @@ -1118,7 +1118,7 @@ int vt_ioctl(struct tty_struct *tty, str return i; } } - + vc->vt_newvt = -1; /* * When we actually do the console switch, * make sure we are atomic with respect to @@ -1173,7 +1173,7 @@ int vt_ioctl(struct tty_struct *tty, str if (get_user(ll, &vtsizes->v_rows) || get_user(cc, &vtsizes->v_cols)) return -EFAULT; - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { + for (i = 0; i < vc->display_fg->vc_count; i++) { struct vc_data *tmp = vc->display_fg->vc_cons[i]; vc_resize(tmp, cc, ll); @@ -1216,7 +1216,7 @@ int vt_ioctl(struct tty_struct *tty, str if (clin > 32) return -EINVAL; - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { + for (i = 0; i < vc->display_fg->vc_count; i++) { struct vc_data *tmp = vc->display_fg->vc_cons[i]; if (vlin) diff -Nurp ruby-CVS/drivers/video/console/dummycon.c ruby-2.6.0-test3/drivers/video/console/dummycon.c --- ruby-CVS/drivers/video/console/dummycon.c 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/drivers/video/console/dummycon.c 2003-09-11 13:44:36.000000000 +0100 @@ -28,13 +28,18 @@ #define DUMMY_COLUMNS 80 #define DUMMY_ROWS 25 #endif +#define MAX_DUMB_CONSOLES 16 +static unsigned long dumb_num = 0; +static unsigned long dumb_vc_count = 0; static struct vt_struct dummy_vt; static struct vc_data default_mode; static const char *dummycon_startup(struct vt_struct *vt, int init) { - vt->default_mode = &default_mode; + vt->default_mode = &default_mode; + vt->default_mode->vc_cols = DUMMY_COLUMNS; + vt->default_mode->vc_rows = DUMMY_ROWS; return "dummy device"; } @@ -83,13 +88,56 @@ int __init dumbcon_init(void) const char *display_desc = NULL; memset(&dummy_vt, 0, sizeof(struct vt_struct)); - dummy_vt.kmalloced = 0; - dummy_vt.vt_sw = &dummy_con; - display_desc = vt_map_display(&dummy_vt, 1); + dummy_vt.vt_kmalloced = 0; + dummy_vt.vt_sw = &dummy_con; + display_desc = vt_map_display(&dummy_vt, 1, MAX_NR_USER_CONSOLES); if (!display_desc) return -ENODEV; - printk("Console: mono %s %dx%d\n", display_desc, + printk("Console: mono %s %dx%d vc:%d-%d\n", display_desc, dummy_vt.default_mode->vc_cols, - dummy_vt.default_mode->vc_rows); + dummy_vt.default_mode->vc_rows, + dummy_vt.first_vc, dummy_vt.first_vc + dummy_vt.vc_count - 1); return 0; } +int dumbcon_add(void) +{ + const char *display_desc = NULL; + struct vt_struct *vt; + + vt = (struct vt_struct *) kmalloc(sizeof(struct vt_struct),GFP_KERNEL); + + if (!vt) return -ENOMEM; + + memset(vt, 0, sizeof(struct vt_struct)); + vt->vt_kmalloced = 1; + vt->vt_sw = &dummy_con; + display_desc = vt_map_display(vt, 1, MAX_NR_USER_CONSOLES); + if (!display_desc) { + kfree(vt); + return -ENODEV; + } + printk("Console: mono %s %dx%d vc:%d-%d\n", display_desc, + vt->default_mode->vc_cols, + vt->default_mode->vc_rows, + vt->first_vc, vt->first_vc + vt->vc_count - 1); + return 0; +} + +int __init dumb_console_init(void) +{ + unsigned long i; + for(i=0; i<dumb_num && i<MAX_DUMB_CONSOLES; i++ ) { + if(dumbcon_add()) return 1; + } + return 0; +} + +int __init dumbcon_setup(char *options) +{ + if (!options || !*options) + return 0; + dumb_num = simple_strtoul(options, 0, 0); + return 0; +} + +__setup("dumbcon=", dumbcon_setup); diff -Nurp ruby-CVS/drivers/video/console/vgacon.c ruby-2.6.0-test3/drivers/video/console/vgacon.c --- ruby-CVS/drivers/video/console/vgacon.c 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/drivers/video/console/vgacon.c 2003-09-11 13:44:36.000000000 +0100 @@ -830,7 +830,7 @@ static int vgacon_do_font_op(struct vgas int i; /* attribute controller */ - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { + for (i = 0; i < vga_vt.vc_count; i++) { struct vc_data *vc = vga_vt.vc_cons[i]; if (vc) @@ -898,11 +898,13 @@ static int vgacon_adjust_height(struct v outb_p(vde, vga_video_port_val); spin_unlock_irq(&vga_lock); - for (i = 0; i < MAX_NR_USER_CONSOLES; i++) { + for (i = 0; i < vc->display_fg->vc_count; i++) { struct vc_data *tmp = vc->display_fg->vc_cons[i]; - if (tmp) + if (tmp) { + tmp->vc_font.height = fontheight; vc_resize(tmp, 0, rows); /* Adjust console size */ + } } return 0; } @@ -1089,14 +1091,15 @@ int __init vga_console_init(void) const char *display_desc = NULL; memset(&vga_vt, 0, sizeof(struct vt_struct)); - vga_vt.kmalloced = 0; + vga_vt.vt_kmalloced = 0; vga_vt.vt_sw = &vga_con; - display_desc = vt_map_display(&vga_vt, 1); + display_desc = vt_map_display(&vga_vt, 1, MAX_NR_USER_CONSOLES); if (!display_desc) return -ENODEV; - printk("Console: %s %s %dx%d\n", + printk("Console: %s %s %dx%d vc:%d-%d\n", vga_vt.default_mode->vc_can_do_color ? "Colour" : "Mono", display_desc, vga_vt.default_mode->vc_cols, - vga_vt.default_mode->vc_rows); + vga_vt.default_mode->vc_rows, + vga_vt.first_vc, vga_vt.first_vc + vga_vt.vc_count - 1); return 0; } diff -Nurp ruby-CVS/include/linux/kbd_kern.h ruby-2.6.0-test3/include/linux/kbd_kern.h --- ruby-CVS/include/linux/kbd_kern.h 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/include/linux/kbd_kern.h 2003-09-11 13:44:36.000000000 +0100 @@ -96,54 +96,54 @@ static inline void set_leds(void) tasklet_schedule(&keyboard_tasklet); } -static inline int get_kbd_mode(struct kbd_struct kbd, int flag) +static inline int get_kbd_mode(struct kbd_struct * kbd, int flag) { - return ((kbd.modeflags >> flag) & 1); + return ((kbd->modeflags >> flag) & 1); } -static inline int get_kbd_led(struct kbd_struct kbd, int flag) +static inline int get_kbd_led(struct kbd_struct * kbd, int flag) { - return ((kbd.ledflagstate >> flag) & 1); + return ((kbd->ledflagstate >> flag) & 1); } -static inline void set_kbd_mode(struct kbd_struct kbd, int flag) +static inline void set_kbd_mode(struct kbd_struct * kbd, int flag) { - kbd.modeflags |= 1 << flag; + kbd->modeflags |= 1 << flag; } -static inline void set_kbd_led(struct kbd_struct kbd, int flag) +static inline void set_kbd_led(struct kbd_struct * kbd, int flag) { - kbd.ledflagstate |= 1 << flag; + kbd->ledflagstate |= 1 << flag; } -static inline void clr_kbd_mode(struct kbd_struct kbd, int flag) +static inline void clr_kbd_mode(struct kbd_struct * kbd, int flag) { - kbd.modeflags &= ~(1 << flag); + kbd->modeflags &= ~(1 << flag); } -static inline void clr_kbd_led(struct kbd_struct kbd, int flag) +static inline void clr_kbd_led(struct kbd_struct * kbd, int flag) { - kbd.ledflagstate &= ~(1 << flag); + kbd->ledflagstate &= ~(1 << flag); } -static inline void chg_kbd_lock(struct kbd_struct kbd, int flag) +static inline void chg_kbd_lock(struct kbd_struct * kbd, int flag) { - kbd.lockstate ^= 1 << flag; + kbd->lockstate ^= 1 << flag; } -static inline void chg_kbd_slock(struct kbd_struct kbd, int flag) +static inline void chg_kbd_slock(struct kbd_struct * kbd, int flag) { - kbd.slockstate ^= 1 << flag; + kbd->slockstate ^= 1 << flag; } -static inline void chg_kbd_mode(struct kbd_struct kbd, int flag) +static inline void chg_kbd_mode(struct kbd_struct * kbd, int flag) { - kbd.modeflags ^= 1 << flag; + kbd->modeflags ^= 1 << flag; } -static inline void chg_kbd_led(struct kbd_struct kbd, int flag) +static inline void chg_kbd_led(struct kbd_struct * kbd, int flag) { - kbd.ledflagstate ^= 1 << flag; + kbd->ledflagstate ^= 1 << flag; } #define U(x) ((x) ^ 0xf000) diff -Nurp ruby-CVS/include/linux/vt_kern.h ruby-2.6.0-test3/include/linux/vt_kern.h --- ruby-CVS/include/linux/vt_kern.h 2003-08-11 17:26:46.000000000 +0100 +++ ruby-2.6.0-test3/include/linux/vt_kern.h 2003-09-11 13:44:36.000000000 +0100 @@ -142,6 +142,7 @@ struct vc_data { unsigned int vc_need_wrap:1; unsigned int vc_can_do_color:1; unsigned int vc_report_mouse:2; + unsigned int vc_kmalloced:1; unsigned char vc_utf:1; /* Unicode UTF-8 encoding */ unsigned char vc_utf_count; int vc_utf_char; @@ -214,7 +215,7 @@ struct vt_struct { struct vc_data *want_vc; /* VC we want to switch to */ int scrollback_delta; int cursor_original; - char kmalloced; /* Did we use kmalloced ? */ + char vt_kmalloced; /* Did we use kmalloced ? */ char vt_dont_switch; /* VC switching flag */ char vt_blanked; /* Is this display blanked */ int blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ @@ -238,6 +239,7 @@ struct vt_struct { struct input_handle *beeper; /* Bell noise support */ void *data_hook; /* Hook for driver data */ unsigned int first_vc; + unsigned int vc_count; struct vc_data *vc_cons[MAX_NR_USER_CONSOLES]; /* VT's VC pool */ struct vt_struct *next; }; @@ -255,7 +257,7 @@ void vte_decsc(struct vc_data *vc); void terminal_emulation(struct tty_struct *tty, int c); /* vt.c */ -const char *vt_map_display(struct vt_struct *vt, int init); +const char *vt_map_display(struct vt_struct *vt, int init, int vc_count); void vt_map_input(struct vt_struct *vt); struct vc_data *find_vc(int currcons); struct vc_data *vc_allocate(unsigned int console); @@ -288,7 +290,8 @@ void update_screen(struct vc_data *vc); inline int resize_screen(struct vc_data *vc, int width, int height); inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed); inline void save_screen(struct vc_data *vc); -void do_blank_screen(int gfx_mode); +void do_blank_screen(struct vt_struct *vt, int gfx_mode); +void unblank_vt(struct vt_struct *vt); void unblank_screen(void); void poke_blanked_console(struct vt_struct *vt); int con_font_op(struct vc_data *vc, struct console_font_op *op); diff -Nurp ruby-CVS/kernel/power/power.h ruby-2.6.0-test3/kernel/power/power.h --- ruby-CVS/kernel/power/power.h 1970-01-01 01:00:00.000000000 +0100 +++ ruby-2.6.0-test3/kernel/power/power.h 2003-09-11 13:44:36.000000000 +0100 @@ -0,0 +1,9 @@ + + +/* With SUSPEND_CONSOLE defined, it suspend looks *really* cool, but + we probably do not take enough locks for switching consoles, etc, + so bad things might happen. +*/ +#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) +//#define SUSPEND_CONSOLE (MAX_NR_USER_CONSOLES-1) +#endif Aivils Stoss |