do the screen switch asynchronously (via timeout(0)) if possible,
this hopefully helps for the (very rare) display corruption reported in PR kern/8628
This commit is contained in:
parent
8996199a85
commit
162086b1cd
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vga.c,v 1.21 1999/11/03 15:55:27 mycroft Exp $ */
|
||||
/* $NetBSD: vga.c,v 1.22 1999/12/06 18:54:50 drochner Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
|
||||
|
@ -98,6 +98,10 @@ struct vga_config {
|
|||
bus_space_handle_t vc_bioshdl;
|
||||
|
||||
struct vgafont *vc_fonts[8];
|
||||
|
||||
struct vgascreen *wantedscreen;
|
||||
void (*switchcb) __P((void *, int, int));
|
||||
void *switchcbarg;
|
||||
};
|
||||
|
||||
static int vgaconsole, vga_console_type, vga_console_attached;
|
||||
|
@ -231,9 +235,12 @@ static int vga_mmap __P((void *, off_t, int));
|
|||
static int vga_alloc_screen __P((void *, const struct wsscreen_descr *,
|
||||
void **, int *, int *, long *));
|
||||
static void vga_free_screen __P((void *, void *));
|
||||
static void vga_show_screen __P((void *, void *));
|
||||
static int vga_show_screen __P((void *, void *, int,
|
||||
void (*) (void *, int, int), void *));
|
||||
static int vga_load_font __P((void *, void *, struct wsdisplay_font *));
|
||||
|
||||
void vga_doswitch __P((struct vga_config *));
|
||||
|
||||
const struct wsdisplay_accessops vga_accessops = {
|
||||
vga_ioctl,
|
||||
vga_mmap,
|
||||
|
@ -704,17 +711,50 @@ vga_setfont(vc, scr)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
vga_show_screen(v, cookie)
|
||||
int
|
||||
vga_show_screen(v, cookie, waitok, cb, cbarg)
|
||||
void *v;
|
||||
void *cookie;
|
||||
int waitok;
|
||||
void (*cb) __P((void *, int, int));
|
||||
void *cbarg;
|
||||
{
|
||||
struct vgascreen *scr = cookie, *oldscr;
|
||||
struct vga_config *vc = scr->cfg;
|
||||
struct vga_handle *vh = &vc->hdl;
|
||||
const struct wsscreen_descr *type = scr->pcs.type;
|
||||
|
||||
oldscr = vc->active; /* can be NULL! */
|
||||
if (scr == oldscr) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
vc->wantedscreen = cookie;
|
||||
vc->switchcb = cb;
|
||||
vc->switchcbarg = cbarg;
|
||||
if (cb) {
|
||||
timeout((void(*)(void *))vga_doswitch, vc, 0);
|
||||
return (EAGAIN);
|
||||
}
|
||||
|
||||
vga_doswitch(vc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
vga_doswitch(vc)
|
||||
struct vga_config *vc;
|
||||
{
|
||||
struct vgascreen *scr, *oldscr;
|
||||
struct vga_handle *vh = &vc->hdl;
|
||||
const struct wsscreen_descr *type;
|
||||
|
||||
scr = vc->wantedscreen;
|
||||
if (!scr) {
|
||||
printf("vga_doswitch: disappeared\n");
|
||||
(*vc->switchcb)(vc->switchcbarg, EIO, 0);
|
||||
return;
|
||||
}
|
||||
type = scr->pcs.type;
|
||||
oldscr = vc->active; /* can be NULL! */
|
||||
#ifdef DIAGNOSTIC
|
||||
if (oldscr) {
|
||||
if (!oldscr->pcs.active)
|
||||
|
@ -763,6 +803,10 @@ vga_show_screen(v, cookie)
|
|||
|
||||
pcdisplay_cursor(&scr->pcs, scr->pcs.cursoron,
|
||||
scr->pcs.vc_crow, scr->pcs.vc_ccol);
|
||||
|
||||
vc->wantedscreen = 0;
|
||||
if (vc->switchcb)
|
||||
(*vc->switchcb)(vc->switchcbarg, 0, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
Loading…
Reference in New Issue