Index: conf/files.i386 =================================================================== RCS file: /usr/cvs/src/sys/conf/files.i386,v retrieving revision 1.597 diff -u -r1.597 files.i386 --- conf/files.i386 14 Jun 2008 12:51:44 -0000 1.597 +++ conf/files.i386 28 Jun 2008 21:49:12 -0000 @@ -337,6 +337,7 @@ i386/isa/atpic.c standard #i386/isa/atpic_vector.s standard i386/isa/clock.c standard +i386/isa/dpms.c optional dpms i386/isa/elcr.c standard i386/isa/elink.c optional ep | ie i386/isa/isa.c optional isa Index: i386/isa/dpms.c =================================================================== RCS file: i386/isa/dpms.c diff -N i386/isa/dpms.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ i386/isa/dpms.c 28 Jun 2008 21:50:02 -0000 @@ -0,0 +1,210 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (c) 2004 Benjamin Close + * + * ??? + */ + +/* + * Support for managing the display via DPMS for suspend/resume. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include + +/* + * VESA DPMS States + */ +#define DPMS_ON 0x00 +#define DPMS_STANDBY 0x01 +#define DPMS_SUSPEND 0x02 +#define DPMS_OFF 0x04 +#define DPMS_REDUCEDON 0x08 + +#define VBE_DPMS_FUNCTION 0x4F10 +#define VBE_DPMS_GET_SUPPORTED_STATES 0x00 +#define VBE_DPMS_GET_STATE 0x02 +#define VBE_DPMS_SET_STATE 0x01 +#define VBE_MAJORVERSION_MASK 0x0F +#define VBE_MINORVERSION_MASK 0xF0 + +struct dpms_softc { + int dpms_supported_states; + int dpms_initial_state; +}; + +static int dpms_attach(device_t); +static int dpms_detach(device_t); +static int dpms_get_supported_states(int *); +static int dpms_get_current_state(int *); +static void dpms_identify(driver_t *, device_t); +static int dpms_probe(device_t); +static int dpms_resume(device_t); +static int dpms_set_state(int); +static int dpms_suspend(device_t); + +static device_method_t dpms_methods[] = { + DEVMETHOD(device_identify, dpms_identify), + DEVMETHOD(device_probe, dpms_probe), + DEVMETHOD(device_attach, dpms_attach), + DEVMETHOD(device_detach, dpms_detach), + DEVMETHOD(device_suspend, dpms_suspend), + DEVMETHOD(device_resume, dpms_resume), + { 0, 0 } +}; + +static driver_t dpms_driver = { + "dpms", + dpms_methods, + sizeof(struct dpms_softc), +}; + +static devclass_t dpms_devclass; + +DRIVER_MODULE(dpms, vgapci, dpms_driver, dpms_devclass, NULL, NULL); + +static void +dpms_identify(driver_t *driver, device_t parent) +{ + + /* + * XXX: The DPMS VBE only allows for manipulating a single + * monitor, but we don't know which one. Just attach to the + * first vgapci(4) device we encounter and hope it is the + * right one. + */ + if (devclass_get_device(dpms_devclass, 0) == NULL) + device_add_child(parent, "dpms", 0); +} + +static int +dpms_probe(device_t dev) +{ + int error, states; + + error = dpms_get_supported_states(&states); + if (error) + return (error); + device_set_desc(dev, "DPMS suspend/resume"); + device_quiet(dev); + return (BUS_PROBE_DEFAULT); +} + +static int +dpms_attach(device_t dev) +{ + struct dpms_softc *sc; + int error; + + sc = device_get_softc(dev); + error = dpms_get_supported_states(&sc->dpms_supported_states); + if (error) + return (error); + error = dpms_get_current_state(&sc->dpms_initial_state); + return (error); +} + +static int +dpms_detach(device_t dev) +{ + + return (0); +} + +static int +dpms_suspend(device_t dev) +{ + + dpms_set_state(DPMS_OFF); + return (0); +} + +static int +dpms_resume(device_t dev) +{ + struct dpms_softc *sc; + + sc = device_get_softc(dev); + dpms_set_state(sc->dpms_initial_state); + return (0); +} + +static int +dpms_call_bios(int subfunction, int *bh) +{ + struct vm86frame vmf; + int error; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_ax = VBE_DPMS_FUNCTION; + vmf.vmf_bl = subfunction; + vmf.vmf_bh = *bh; + vmf.vmf_es = 0; + vmf.vmf_di = 0; + error = vm86_intcall(0x10, &vmf); + if (error == 0 && (vmf.vmf_eax & 0xffff) != 0x004f) + error = ENXIO; + if (error == 0) + *bh = vmf.vmf_bh; + return (error); +} + +static int +dpms_get_supported_states(int *states) +{ + + *states = 0; + return (dpms_call_bios(VBE_DPMS_GET_SUPPORTED_STATES, states)); +} + +static int +dpms_get_current_state(int *state) +{ + + *state = 0; + return (dpms_call_bios(VBE_DPMS_GET_STATE, state)); +} + +static int +dpms_set_state(int state) +{ + + return (dpms_call_bios(VBE_DPMS_SET_STATE, &state)); +} Index: modules/Makefile =================================================================== RCS file: /usr/cvs/src/sys/modules/Makefile,v retrieving revision 1.574 diff -u -r1.574 Makefile --- modules/Makefile 20 Jun 2008 19:28:33 -0000 1.574 +++ modules/Makefile 28 Jun 2008 21:49:12 -0000 @@ -74,6 +74,7 @@ dcons_crom \ de \ ${_digi} \ + ${_dpms} \ ${_dpt} \ ${_drm} \ ${_dtrace} \ @@ -389,6 +390,7 @@ _cyclic= cyclic .endif _digi= digi +_dpms= dpms _drm= drm .if ${MK_CDDL} != "no" || defined(ALL_MODULES) _dtrace= dtrace Index: modules/dpms/Makefile =================================================================== RCS file: modules/dpms/Makefile diff -N modules/dpms/Makefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/dpms/Makefile 28 Jun 2008 21:49:29 -0000 @@ -0,0 +1,9 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../i386/isa + +KMOD= dpms +SRCS= dpms.c +SRCS+= bus_if.h device_if.h + +.include