X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=blobdiff_plain;f=drivers%2Fxen%2Fconsole%2Fconsole.c;h=66f455fb4d9d30d7c996b37e48425f397a7c5bdc;hp=ec7dd9e58447723255c9b2720da57e0d0a1c21c1;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hpb=4e76c8a9fa413ccc09d3f7f664183dcce3555d57 diff --git a/drivers/xen/console/console.c b/drivers/xen/console/console.c index ec7dd9e58..66f455fb4 100644 --- a/drivers/xen/console/console.c +++ b/drivers/xen/console/console.c @@ -30,7 +30,6 @@ * IN THE SOFTWARE. */ -#include #include #include #include @@ -39,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -57,20 +58,28 @@ #include #include #include +#include /* * Modes: * 'xencons=off' [XC_OFF]: Console is disabled. * 'xencons=tty' [XC_TTY]: Console attached to '/dev/tty[0-9]+'. * 'xencons=ttyS' [XC_SERIAL]: Console attached to '/dev/ttyS[0-9]+'. + * 'xencons=xvc' [XC_XVC]: Console attached to '/dev/xvc[0-9]+'. * [XC_DEFAULT]: DOM0 -> XC_SERIAL ; all others -> XC_TTY. * * NB. In mode XC_TTY, we create dummy consoles for tty2-63. This suppresses * warnings from standard distro startup scripts. */ -static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT; +static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL, XC_XVC } + xc_mode = XC_DEFAULT; static int xc_num = -1; +/* If we are in XC_XVC mode (a virtual console at /dev/xvcX), we need to + * comply with Lanana and use a minor under the low density serial major. + */ +#define XEN_XVC_MINOR 187 + #ifdef CONFIG_MAGIC_SYSRQ static unsigned long sysrq_requested; extern int sysrq_enabled; @@ -85,6 +94,8 @@ static int __init xencons_setup(char *str) xc_mode = XC_SERIAL; else if (!strncmp(str, "tty", 3)) xc_mode = XC_TTY; + else if (!strncmp(str, "xvc", 3)) + xc_mode = XC_XVC; else if (!strncmp(str, "off", 3)) xc_mode = XC_OFF; @@ -99,6 +110,11 @@ static int __init xencons_setup(char *str) if (q > (str + 3)) xc_num = n; break; + case XC_XVC: + n = simple_strtol(str+3, &q, 10); + if (q > (str + 3)) + xc_num = n; + break; default: break; } @@ -182,23 +198,30 @@ static struct console kcons_info = { .index = -1, }; -#define __RETCODE 0 static int __init xen_console_init(void) { if (!is_running_on_xen()) - return __RETCODE; + goto out; - if (xen_start_info->flags & SIF_INITDOMAIN) { + if (is_initial_xendomain()) { if (xc_mode == XC_DEFAULT) xc_mode = XC_SERIAL; kcons_info.write = kcons_write_dom0; } else { + if (!xen_start_info->console.domU.evtchn) + goto out; if (xc_mode == XC_DEFAULT) - xc_mode = XC_TTY; + xc_mode = XC_XVC; kcons_info.write = kcons_write; } switch (xc_mode) { + case XC_XVC: + strcpy(kcons_info.name, "xvc"); + if (xc_num == -1) + xc_num = 0; + break; + case XC_SERIAL: strcpy(kcons_info.name, "ttyS"); if (xc_num == -1) @@ -212,14 +235,15 @@ static int __init xen_console_init(void) break; default: - return __RETCODE; + goto out; } wbuf = alloc_bootmem(wbuf_size); register_console(&kcons_info); - return __RETCODE; + out: + return 0; } console_initcall(xen_console_init); @@ -247,7 +271,9 @@ void xencons_force_flush(void) int sz; /* Emergency console is synchronous, so there's nothing to flush. */ - if (xen_start_info->flags & SIF_INITDOMAIN) + if (!is_running_on_xen() || + is_initial_xendomain() || + !xen_start_info->console.domU.evtchn) return; /* Spin until console data is flushed through to the daemon. */ @@ -262,10 +288,45 @@ void xencons_force_flush(void) } +void dom0_init_screen_info(const struct dom0_vga_console_info *info) +{ + switch (info->video_type) { + case XEN_VGATYPE_TEXT_MODE_3: + screen_info.orig_video_mode = 3; + screen_info.orig_video_ega_bx = 3; + screen_info.orig_video_isVGA = 1; + screen_info.orig_video_lines = info->u.text_mode_3.rows; + screen_info.orig_video_cols = info->u.text_mode_3.columns; + screen_info.orig_x = info->u.text_mode_3.cursor_x; + screen_info.orig_y = info->u.text_mode_3.cursor_y; + screen_info.orig_video_points = + info->u.text_mode_3.font_height; + break; + case XEN_VGATYPE_VESA_LFB: + screen_info.orig_video_isVGA = VIDEO_TYPE_VLFB; + screen_info.lfb_width = info->u.vesa_lfb.width; + screen_info.lfb_height = info->u.vesa_lfb.height; + screen_info.lfb_depth = info->u.vesa_lfb.bits_per_pixel; + screen_info.lfb_base = info->u.vesa_lfb.lfb_base; + screen_info.lfb_size = info->u.vesa_lfb.lfb_size; + screen_info.lfb_linelength = info->u.vesa_lfb.bytes_per_line; + screen_info.red_size = info->u.vesa_lfb.red_size; + screen_info.red_pos = info->u.vesa_lfb.red_pos; + screen_info.green_size = info->u.vesa_lfb.green_size; + screen_info.green_pos = info->u.vesa_lfb.green_pos; + screen_info.blue_size = info->u.vesa_lfb.blue_size; + screen_info.blue_pos = info->u.vesa_lfb.blue_pos; + screen_info.rsvd_size = info->u.vesa_lfb.rsvd_size; + screen_info.rsvd_pos = info->u.vesa_lfb.rsvd_pos; + break; + } +} + + /******************** User-space console driver (/dev/console) ************/ #define DRV(_d) (_d) -#define DUMMY_TTY(_tty) ((xc_mode != XC_SERIAL) && \ +#define DUMMY_TTY(_tty) ((xc_mode != XC_SERIAL) && (xc_mode != XC_XVC) && \ ((_tty)->index != (xc_num - 1))) static struct termios *xencons_termios[MAX_NR_CONSOLES]; @@ -318,7 +379,7 @@ static void __xencons_tx_flush(void) int sent, sz, work_done = 0; if (x_char) { - if (xen_start_info->flags & SIF_INITDOMAIN) + if (is_initial_xendomain()) kcons_write_dom0(NULL, &x_char, 1); else while (x_char) @@ -332,7 +393,7 @@ static void __xencons_tx_flush(void) sz = wp - wc; if (sz > (wbuf_size - WBUF_MASK(wc))) sz = wbuf_size - WBUF_MASK(wc); - if (xen_start_info->flags & SIF_INITDOMAIN) { + if (is_initial_xendomain()) { kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz); wc += sz; } else { @@ -582,9 +643,14 @@ static int __init xencons_init(void) if (xc_mode == XC_OFF) return 0; - xencons_ring_init(); + if (!is_initial_xendomain()) { + rc = xencons_ring_init(); + if (rc) + return rc; + } - xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ? + xencons_driver = alloc_tty_driver(((xc_mode == XC_SERIAL) || + (xc_mode == XC_XVC)) ? 1 : MAX_NR_CONSOLES); if (xencons_driver == NULL) return -ENOMEM; @@ -604,6 +670,11 @@ static int __init xencons_init(void) DRV(xencons_driver)->name = "ttyS"; DRV(xencons_driver)->minor_start = 64 + xc_num; DRV(xencons_driver)->name_base = 0 + xc_num; + } else if (xc_mode == XC_XVC) { + DRV(xencons_driver)->name = "xvc"; + DRV(xencons_driver)->major = 250; /* FIXME: until lanana approves for 204:187 */ + DRV(xencons_driver)->minor_start = XEN_XVC_MINOR; + DRV(xencons_driver)->name_base = xc_num; } else { DRV(xencons_driver)->name = "tty"; DRV(xencons_driver)->minor_start = 1; @@ -622,7 +693,7 @@ static int __init xencons_init(void) return rc; } - if (xen_start_info->flags & SIF_INITDOMAIN) { + if (is_initial_xendomain()) { xencons_priv_irq = bind_virq_to_irqhandler( VIRQ_CONSOLE, 0, @@ -636,6 +707,20 @@ static int __init xencons_init(void) printk("Xen virtual console successfully installed as %s%d\n", DRV(xencons_driver)->name, xc_num); + /* Don't need to check about graphical fb for domain 0 */ + if (is_initial_xendomain()) + return 0; + + rc = 0; + if (xenbus_scanf(XBT_NIL, "console", "use_graphics", "%d", &rc) < 0) + printk(KERN_ERR "Unable to read console/use_graphics\n"); + if (rc == 0) { + /* FIXME: this is ugly */ + unregister_console(&kcons_info); + kcons_info.flags |= CON_CONSDEV; + register_console(&kcons_info); + } + return 0; }