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:
drochner 1999-12-06 18:54:50 +00:00
parent 8996199a85
commit 162086b1cd
1 changed files with 50 additions and 6 deletions

View File

@ -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