diff options
author | jkim <jkim@FreeBSD.org> | 2009-11-05 22:58:50 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2009-11-05 22:58:50 +0000 |
commit | bc53678aaf2e4a99efcef14a1b53d0ac50403b83 (patch) | |
tree | 04dc58e4b98fb82187ea223ad1ac4b66c38c4c65 /sys | |
parent | b7d759e2ccf64c56e17c806c07398a5a7090df00 (diff) | |
download | FreeBSD-src-bc53678aaf2e4a99efcef14a1b53d0ac50403b83.zip FreeBSD-src-bc53678aaf2e4a99efcef14a1b53d0ac50403b83.tar.gz |
Save/restore VGA state from vga_pci.c instead of relying on vga_isa.c.
It was not working because we were saving its state after the device was
powered down. Simplify vesa_load_state() as the culprit is fixed now.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/fb/vesa.c | 54 | ||||
-rw-r--r-- | sys/dev/pci/vga_pci.c | 82 | ||||
-rw-r--r-- | sys/isa/vga_isa.c | 37 |
3 files changed, 103 insertions, 70 deletions
diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c index 5403352..36b05f8 100644 --- a/sys/dev/fb/vesa.c +++ b/sys/dev/fb/vesa.c @@ -164,7 +164,6 @@ static char *vesa_revstr = NULL; static int int10_set_mode(int mode); static int vesa_bios_post(void); static int vesa_bios_get_mode(int mode, struct vesa_mode *vmode); -static int vesa_bios_get_current_mode(void); static int vesa_bios_set_mode(int mode); static int vesa_bios_get_dac(void); static int vesa_bios_set_dac(int bits); @@ -319,22 +318,6 @@ vesa_bios_get_mode(int mode, struct vesa_mode *vmode) } static int -vesa_bios_get_current_mode(void) -{ - x86regs_t regs; - - x86bios_init_regs(®s); - regs.R_AX = 0x4f03; - - x86bios_intr(®s, 0x10); - - if (regs.R_AX != 0x004f) - return (-1); - - return (regs.R_BX); -} - -static int vesa_bios_set_mode(int mode) { x86regs_t regs; @@ -1438,7 +1421,6 @@ vesa_save_state(video_adapter_t *adp, void *p, size_t size) static int vesa_load_state(video_adapter_t *adp, void *p) { - int flags, mode, ret; if ((adp != vesa_adp) || (((adp_state_t *)p)->sig != V_STATE_SIG)) return ((*prevvidsw->load_state)(adp, p)); @@ -1446,38 +1428,12 @@ vesa_load_state(video_adapter_t *adp, void *p) if (vesa_state_buf_size <= 0) return (1); - /* - * If the current mode is not the same, probably it was powered down. - * Try BIOS POST to restore a sane state. - */ - if (VESA_MODE(adp->va_mode)) { - mode = vesa_bios_get_current_mode(); - if (mode >= 0 && (mode & 0x1ff) != adp->va_mode) - (void)vesa_bios_post(); - } - - ret = vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, - vesa_state_buf_size); + /* Try BIOS POST to restore a sane state. */ + (void)vesa_bios_post(); + (void)int10_set_mode(adp->va_initial_bios_mode); - /* - * If the desired mode is not restored, force setting the mode. - */ - if (VESA_MODE(adp->va_mode)) { - mode = vesa_bios_get_current_mode(); - if (mode < 0 || (mode & 0x1ff) == adp->va_mode) - return (ret); - mode = adp->va_mode; - flags = adp->va_info.vi_flags; - if ((flags & V_INFO_GRAPHICS) != 0 && - (flags & V_INFO_LINEAR) != 0) - mode |= 0x4000; - (void)vesa_bios_set_mode(mode); - if ((vesa_adp_info->v_flags & V_DAC8) != 0) - (void)vesa_bios_set_dac(8); - (void)(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); - } - - return (ret); + return (vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, + vesa_state_buf_size)); } #if 0 diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c index 1467bbd..07b5ed0 100644 --- a/sys/dev/pci/vga_pci.c +++ b/sys/dev/pci/vga_pci.c @@ -40,12 +40,17 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/bus.h> +#include <sys/fbio.h> #include <sys/kernel.h> +#include <sys/malloc.h> #include <sys/module.h> #include <sys/rman.h> #include <sys/sysctl.h> #include <sys/systm.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/vgareg.h> + #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> @@ -63,7 +68,7 @@ SYSCTL_DECL(_hw_pci); int vga_pci_default_unit = -1; TUNABLE_INT("hw.pci.default_vgapci_unit", &vga_pci_default_unit); -SYSCTL_INT(_hw_pci, OID_AUTO, default_vgapci_unit, CTLFLAG_RD, +SYSCTL_INT(_hw_pci, OID_AUTO, default_vgapci_unit, CTLFLAG_RDTUN, &vga_pci_default_unit, -1, "Default VGA-compatible display"); static int @@ -112,13 +117,86 @@ vga_pci_attach(device_t dev) static int vga_pci_suspend(device_t dev) { + vga_softc_t *sc; + devclass_t dc; + int err, nbytes; + + err = bus_generic_suspend(dev); + if (err) + return (err); + + sc = NULL; + if (device_get_unit(dev) == vga_pci_default_unit) { + dc = devclass_find(VGA_DRIVER_NAME); + if (dc != NULL) + sc = devclass_get_softc(dc, 0); + } + if (sc == NULL) + return (0); + + /* Save the video state across the suspend. */ + if (sc->state_buf != NULL) + goto save_palette; + nbytes = vidd_save_state(sc->adp, NULL, 0); + if (nbytes <= 0) + goto save_palette; + sc->state_buf = malloc(nbytes, M_TEMP, M_NOWAIT); + if (sc->state_buf == NULL) + goto save_palette; + if (bootverbose) + device_printf(dev, "saving %d bytes of video state\n", nbytes); + if (vidd_save_state(sc->adp, sc->state_buf, nbytes) != 0) { + device_printf(dev, "failed to save state (nbytes=%d)\n", + nbytes); + free(sc->state_buf, M_TEMP); + sc->state_buf = NULL; + } + +save_palette: + /* Save the color palette across the suspend. */ + if (sc->pal_buf != NULL) + return (0); + sc->pal_buf = malloc(256 * 3, M_TEMP, M_NOWAIT); + if (sc->pal_buf != NULL) { + if (bootverbose) + device_printf(dev, "saving color palette\n"); + if (vidd_save_palette(sc->adp, sc->pal_buf) != 0) { + device_printf(dev, "failed to save palette\n"); + free(sc->pal_buf, M_TEMP); + sc->pal_buf = NULL; + } + } - return (bus_generic_suspend(dev)); + return (0); } static int vga_pci_resume(device_t dev) { + vga_softc_t *sc; + devclass_t dc; + + sc = NULL; + if (device_get_unit(dev) == vga_pci_default_unit) { + dc = devclass_find(VGA_DRIVER_NAME); + if (dc != NULL) + sc = devclass_get_softc(dc, 0); + } + if (sc == NULL) + return (bus_generic_resume(dev)); + + if (sc->state_buf != NULL) { + if (vidd_load_state(sc->adp, sc->state_buf) != 0) + device_printf(dev, "failed to reload state\n"); + free(sc->state_buf, M_TEMP); + sc->state_buf = NULL; + } + if (sc->pal_buf != NULL) { + if (vidd_load_palette(sc->adp, sc->pal_buf) != 0) + device_printf(dev, "failed to reload palette\n"); + free(sc->pal_buf, M_TEMP); + sc->pal_buf = NULL; + } return (bus_generic_resume(dev)); } diff --git a/sys/isa/vga_isa.c b/sys/isa/vga_isa.c index d31df7e..cfb36ae 100644 --- a/sys/isa/vga_isa.c +++ b/sys/isa/vga_isa.c @@ -166,35 +166,34 @@ isavga_suspend(device_t dev) vga_softc_t *sc; int err, nbytes; - sc = device_get_softc(dev); err = bus_generic_suspend(dev); if (err) return (err); + sc = device_get_softc(dev); + /* Save the video state across the suspend. */ - if (sc->state_buf != NULL) { - free(sc->state_buf, M_TEMP); - sc->state_buf = NULL; - } + if (sc->state_buf != NULL) + goto save_palette; nbytes = vidd_save_state(sc->adp, NULL, 0); if (nbytes <= 0) - return (0); + goto save_palette; sc->state_buf = malloc(nbytes, M_TEMP, M_NOWAIT); - if (sc->state_buf != NULL) { - if (bootverbose) - device_printf(dev, "saving %d bytes of video state\n", - nbytes); - if (vidd_save_state(sc->adp, sc->state_buf, nbytes) != 0) { - device_printf(dev, "failed to save state (nbytes=%d)\n", - nbytes); - free(sc->state_buf, M_TEMP); - sc->state_buf = NULL; - } + if (sc->state_buf == NULL) + goto save_palette; + if (bootverbose) + device_printf(dev, "saving %d bytes of video state\n", nbytes); + if (vidd_save_state(sc->adp, sc->state_buf, nbytes) != 0) { + device_printf(dev, "failed to save state (nbytes=%d)\n", + nbytes); + free(sc->state_buf, M_TEMP); + sc->state_buf = NULL; } +save_palette: /* Save the color palette across the suspend. */ if (sc->pal_buf != NULL) - free(sc->pal_buf, M_TEMP); + return (0); sc->pal_buf = malloc(256 * 3, M_TEMP, M_NOWAIT); if (sc->pal_buf != NULL) { if (bootverbose) @@ -215,6 +214,7 @@ isavga_resume(device_t dev) vga_softc_t *sc; sc = device_get_softc(dev); + if (sc->state_buf != NULL) { if (vidd_load_state(sc->adp, sc->state_buf) != 0) device_printf(dev, "failed to reload state\n"); @@ -228,8 +228,7 @@ isavga_resume(device_t dev) sc->pal_buf = NULL; } - bus_generic_resume(dev); - return 0; + return (bus_generic_resume(dev)); } #ifdef FB_INSTALL_CDEV |