Index: dev/fb/vgareg.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/fb/vgareg.h,v retrieving revision 1.7 diff -u -r1.7 vgareg.h --- dev/fb/vgareg.h 16 Jun 2004 09:46:43 -0000 1.7 +++ dev/fb/vgareg.h 27 Feb 2005 02:37:20 -0000 @@ -69,6 +69,7 @@ struct video_adapter; typedef struct vga_softc { struct video_adapter *adp; + void *state_buf; #ifdef FB_INSTALL_CDEV genfb_softc_t gensc; #endif Index: i386/isa/vesa.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/i386/isa/vesa.c,v retrieving revision 1.47 diff -u -r1.47 vesa.c --- i386/isa/vesa.c 15 Jul 2004 08:26:05 -0000 1.47 +++ i386/isa/vesa.c 28 Feb 2005 20:03:32 -0000 @@ -187,6 +187,7 @@ #define STATE_REG (1<<3) #define STATE_MOST (STATE_HW | STATE_DATA | STATE_REG) #define STATE_ALL (STATE_HW | STATE_DATA | STATE_DAC | STATE_REG) +#define STATE_MAXSIZE (2 * PAGE_SIZE) static int vesa_bios_state_buf_size(void); static int vesa_bios_save_restore(int code, void *p, size_t size); static int vesa_bios_get_line_length(void); @@ -423,7 +424,7 @@ bzero(&vmf, sizeof(vmf)); vmf.vmf_eax = 0x4f04; - vmf.vmf_ecx = STATE_MOST; + vmf.vmf_ecx = STATE_ALL; vmf.vmf_edx = STATE_SIZE; err = vm86_intcall(0x10, &vmf); if ((err != 0) || (vmf.vmf_ax != 0x4f)) @@ -438,15 +439,19 @@ u_char *buf; int err; + if (size > STATE_MAXSIZE) + return (1); + bzero(&vmf, sizeof(vmf)); vmf.vmf_eax = 0x4f04; - vmf.vmf_ecx = STATE_MOST; + vmf.vmf_ecx = STATE_ALL; vmf.vmf_edx = code; /* STATE_SAVE/STATE_LOAD */ buf = (u_char *)vm86_getpage(&vesa_vmcontext, 1); vm86_getptr(&vesa_vmcontext, (vm_offset_t)buf, &vmf.vmf_es, &vmf.vmf_bx); bcopy(p, buf, size); err = vm86_datacall(0x10, &vmf, &vesa_vmcontext); + bcopy(buf, p, size); return ((err != 0) || (vmf.vmf_ax != 0x4f)); } @@ -797,7 +802,12 @@ printf("VESA: %d mode(s) found\n", modes); has_vesa_bios = (modes > 0); - return (has_vesa_bios ? 0 : 1); + if (!has_vesa_bios) + return (1); + + /* Get a second page to support STATE_MAXSIZE. */ + (void)vm86_addpage(&vesa_vmcontext, 2, 0); + return (0); } static void Index: isa/vga_isa.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/isa/vga_isa.c,v retrieving revision 1.31 diff -u -r1.31 vga_isa.c --- isa/vga_isa.c 3 Nov 2004 09:07:44 -0000 1.31 +++ isa/vga_isa.c 28 Feb 2005 20:07:52 -0000 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -160,6 +161,58 @@ return 0; } +static int +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); + + /* Save the video state across the suspend. */ + if (sc->state_buf != NULL) { + free(sc->state_buf, M_TEMP); + sc->state_buf = NULL; + } + nbytes = (*vidsw[sc->adp->va_index]->save_state)(sc->adp, NULL, 0); + if (nbytes <= 0) + return (0); + sc->state_buf = malloc(nbytes, M_TEMP, M_NOWAIT | M_ZERO); + if (sc->state_buf == NULL) + return (0); + if (bootverbose) + device_printf(dev, "saving %d bytes of video state\n", nbytes); + if ((*vidsw[sc->adp->va_index]->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; + } + return (0); +} + +static int +isavga_resume(device_t dev) +{ + vga_softc_t *sc; + + sc = device_get_softc(dev); + if (sc->state_buf != NULL) { + if ((*vidsw[sc->adp->va_index]->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; + } + + bus_generic_resume(dev); + return 0; +} + #ifdef FB_INSTALL_CDEV static int @@ -204,6 +257,8 @@ DEVMETHOD(device_identify, isavga_identify), DEVMETHOD(device_probe, isavga_probe), DEVMETHOD(device_attach, isavga_attach), + DEVMETHOD(device_suspend, isavga_suspend), + DEVMETHOD(device_resume, isavga_resume), DEVMETHOD(bus_print_child, bus_generic_print_child), { 0, 0 }