NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/41415: Virtual console text is entirely lost after exiting Xorg.



>Number:         41415
>Category:       kern
>Synopsis:       Virtual console text is entirely lost after exiting Xorg.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue May 12 18:10:00 +0000 2009
>Originator:     IdOp
>Release:        5.0 -release
>Organization:
>Environment:
NetBSD throne.lan 5.0 NetBSD 5.0 (GENERIC) #0: Sun Apr 26 18:50:08 UTC 2009  
builds%b6.netbsd.org@localhost:/home/builds/ab/netbsd-5-0-RELEASE/i386/200904260229Z-obj/home/builds/ab/netbsd-5-0-RELEASE/src/sys/arch/i386/compile/GENERIC
 i386
>Description:
Xorg runs fine, but after closing the X session all text on the
virtual consoles is permanently lost, although the OS is still
running. This problem was introduced on NetBSD -release at 5.0 with
Xorg; it did not happen on 4.0.1 with XFree86.

The problem happens both with standard vga text-mode console and also
with framebuffer graphics-mode console.  It isn't the result of an
improper xorg.conf file, as it also happens using (a) no xorg.conf
file, and (b) the xorg.conf file generated by "Xorg -configure".

Architecture is i386, GENERIC kernel, and the graphics card is an ATI
rage128 AGP.

Further discussion of this problem may be found on a thread at
DaemonForums.org:

http://www.daemonforums.org/showthread.php?p=23672#post23672

Note: In that thread the same problem was originally noted in OpenBSD
4.3 and 4.4 but it was fixed by OpenBSD 4.5.

>How-To-Repeat:
On affected hardware, remove any default xorg.conf file, run "startx" and then 
exit X with Ctrl-Alt-Backspace.

>Fix:
Below is a kernel patch for NetBSD 5.0 -release which seems to fix the
problem. It may not be an optimal patch.  This patch was put together
by poster BSDfan666 at DaemonForums based on OpenBSD's fix (with one
minor change to the patch by IdOp to make it compile properly).  The
basic idea of the patch is to save, and restore,  vga configuration
info before, and after, running Xorg.

Please note:

- the patch below is *reversed* and relative to 5.0 -release.

- the patch fixes the problem only for text-mode consoles;
  the problem still continues to happen for framebuffer consoles

- dmesg available on request

Thank you.
----------------------begin patch----------------------
--- sys/dev/ic/vga.c    2009-05-09 16:21:29.000000000 -0400
+++ sys/dev/ic/vga.c.orig       2009-05-09 16:18:14.000000000 -0400
@@ -105,6 +105,7 @@
        /* videostate */
        struct egavga_font *fontset1, *fontset2;
        /* font data */
+       /* palette */
 
        int mindispoffset, maxdispoffset;
        int vga_rollover;
@@ -592,8 +593,6 @@
        if (!vh->vh_mono && (u_int)WSDISPLAY_BORDER_COLOR < sizeof(fgansitopc))
                _vga_attr_write(vh, VGA_ATC_OVERSCAN,
                                fgansitopc[WSDISPLAY_BORDER_COLOR]);
-
-       vga_save_palette(vc);
 }
 
 void
@@ -797,7 +796,6 @@
 int
 vga_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
 {
-       int mode;
        struct vga_config *vc = v;
        struct vgascreen *scr = vs;
        const struct vga_funcs *vf = vc->vc_funcs;
@@ -811,12 +809,6 @@
                /* XXX should get detailed hardware information here */
                return EPASSTHROUGH;
 
-       case WSDISPLAYIO_SMODE:
-               mode = *(u_int *)data;
-               if (mode == WSDISPLAYIO_MODE_EMUL)
-                       vga_restore_palette(vc);
-               return 0;
-
        case WSDISPLAYIO_GVIDEO:
                *(int *)data = (vga_get_video(vc) ?
                    WSDISPLAYIO_VIDEO_ON : WSDISPLAYIO_VIDEO_OFF);
@@ -1065,7 +1057,7 @@
        }
 
        vga_setfont(vc, scr);
-       vga_restore_palette(vc);
+       /* XXX swich colours! */
 
        scr->pcs.visibleoffset = scr->pcs.dispoffset = scr->mindispoffset;
        if (!oldscr || (scr->pcs.dispoffset != oldscr->pcs.dispoffset)) {
@@ -1509,40 +1501,3 @@
        vga_initregs(&sc->sc_vc->hdl);
 #endif
 }
-
-void
-vga_save_palette(struct vga_config *vc)
-{
-       struct vga_handle *vh = &vc->hdl;
-       uint i;
-       u_int8_t *palette = vc->vc_palette;
-
-       if (vh->vh_mono)
-               return;
-
-       vga_raw_write(vh, VGA_DAC_PELMASK, 0xff);
-       vga_raw_write(vh, VGA_DAC_ADDRR, 0x00);
-       for (i = 0; i < 3 * 256; i++)
-               *palette++ = vga_raw_read(vh, VGA_DAC_PALETTE);
-
-       vga_raw_read(vh, 0x0a);                 /* reset flip/flop */
-}
-
-void
-vga_restore_palette(struct vga_config *vc)
-{
-       struct vga_handle *vh = &vc->hdl;
-       uint i;
-       u_int8_t *palette = vc->vc_palette;
-
-       if (vh->vh_mono)
-               return;
-
-       vga_raw_write(vh, VGA_DAC_PELMASK, 0xff);
-       vga_raw_write(vh, VGA_DAC_ADDRW, 0x00);
-       for (i = 0; i < 3 * 256; i++)
-               vga_raw_write(vh, VGA_DAC_PALETTE, *palette++);
-
-       vga_raw_read(vh, 0x0a);                 /* reset flip/flop */
-       vga_enable(vh);
-}
--- sys/dev/ic/vgavar.h 2009-05-10 23:12:36.000000000 -0400
+++ sys/dev/ic/vgavar.h.orig    2009-05-09 16:18:24.000000000 -0400
@@ -59,9 +59,6 @@
        bus_space_tag_t vc_biostag;
        bus_space_handle_t vc_bioshdl;
 
-        /* perhaps not the optimal location? */
-        uint8_t vc_palette[256 * 3];
-    
        struct vgascreen *wantedscreen;
        void (*switchcb)(void *, int, int);
        void *switchcbarg;
@@ -75,7 +72,6 @@
        int currentfontset1, currentfontset2;
        int vc_nfontslots;
        struct egavga_font *vc_fonts[8]; /* currently loaded */
-       u_int8_t palette[256 * 3];
        TAILQ_HEAD(, egavga_font) vc_fontlist; /* LRU queue */
 #else
        int nfonts;
@@ -95,14 +91,6 @@
 static __inline u_int8_t       _vga_gdc_read(struct vga_handle *, int);
 static __inline void   _vga_gdc_write(struct vga_handle *, int, u_int8_t);
 
-#define        vga_raw_read(vh, reg) \
-       bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, reg)
-#define        vga_raw_write(vh, reg, value) \
-       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, reg, value)
-
-#define        vga_enable(vh) \
-       vga_raw_write(vh, 0, 0x20);
-
 static __inline u_int8_t
 _vga_attr_read(struct vga_handle *vh, int reg)
 {
@@ -111,14 +99,14 @@
        /* reset state */
        (void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10);
 
-       vga_raw_write(vh, VGA_ATC_INDEX, reg);
-       res = vga_raw_read(vh, VGA_ATC_DATAR);
+       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_INDEX, reg);
+       res = bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_DATAR);
 
        /* reset state XXX unneeded? */
        (void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10);
 
        /* enable */
-       vga_enable(vh);
+       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, 0, 0x20);
 
        return (res);
 }
@@ -130,45 +118,46 @@
        /* reset state */
        (void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10);
 
-       vga_raw_write(vh, VGA_ATC_INDEX, reg);
-       vga_raw_write(vh, VGA_ATC_DATAW, val);
+       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_INDEX, reg);
+       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_ATC_DATAW, val);
 
        /* reset state XXX unneeded? */
        (void) bus_space_read_1(vh->vh_iot, vh->vh_ioh_6845, 10);
 
-       vga_enable(vh);
+       /* enable */
+       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, 0, 0x20);
 }
 
 static __inline u_int8_t
 _vga_ts_read(struct vga_handle *vh, int reg)
 {
 
-       vga_raw_write(vh, VGA_TS_INDEX, reg);
-       return (vga_raw_read(vh, VGA_TS_DATA));
+       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_INDEX, reg);
+       return (bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_DATA));
 }
 
 static __inline void
 _vga_ts_write(struct vga_handle *vh, int reg, u_int8_t val)
 {
 
-       vga_raw_write(vh, VGA_TS_INDEX, reg);
-       vga_raw_write(vh, VGA_TS_DATA, val);
+       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_INDEX, reg);
+       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_TS_DATA, val);
 }
 
 static __inline u_int8_t
 _vga_gdc_read(struct vga_handle *vh, int reg)
 {
 
-       vga_raw_write(vh, VGA_GDC_INDEX, reg);
-       return (vga_raw_read(vh, VGA_GDC_DATA));
+       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_INDEX, reg);
+       return (bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_DATA));
 }
 
 static __inline void
 _vga_gdc_write(struct vga_handle *vh, int reg, u_int8_t val)
 {
 
-       vga_raw_write(vh, VGA_GDC_INDEX, reg);
-       vga_raw_write(vh, VGA_GDC_DATA, val);
+       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_INDEX, reg);
+       bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga, VGA_GDC_DATA, val);
 }
 
 #define vga_attr_read(vh, reg) \
@@ -209,8 +198,6 @@
 struct wsscreen_descr;
 void   vga_loadchars(struct vga_handle *, int, int, int, int, const char *);
 void   vga_readoutchars(struct vga_handle *, int, int, int, int, char *);
-void   vga_restore_palette(struct vga_config *);
-void   vga_save_palette(struct vga_config *);
 #ifdef VGA_CONSOLE_ATI_BROKEN_FONTSEL
 void   vga_copyfont01(struct vga_handle *);
 #endif
---------------------------end patch---------------------------



Home | Main Index | Thread Index | Old Index