dpms.c (197022) | dpms.c (197025) |
---|---|
1/*- 2 * Copyright (c) 2008 Yahoo!, Inc. 3 * All rights reserved. 4 * Written by: John Baldwin <jhb@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 45 unchanged lines hidden (view full) --- 54 * SUCH DAMAGE. 55 */ 56 57/* 58 * Support for managing the display via DPMS for suspend/resume. 59 */ 60 61#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2008 Yahoo!, Inc. 3 * All rights reserved. 4 * Written by: John Baldwin <jhb@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 45 unchanged lines hidden (view full) --- 54 * SUCH DAMAGE. 55 */ 56 57/* 58 * Support for managing the display via DPMS for suspend/resume. 59 */ 60 61#include <sys/cdefs.h> |
62__FBSDID("$FreeBSD: head/sys/dev/dpms/dpms.c 197022 2009-09-09 07:45:08Z delphij $"); | 62__FBSDID("$FreeBSD: head/sys/dev/dpms/dpms.c 197025 2009-09-09 09:50:31Z delphij $"); |
63 64#include <sys/param.h> 65#include <sys/bus.h> 66#include <sys/kernel.h> 67#include <sys/libkern.h> 68#include <sys/module.h> 69 | 63 64#include <sys/param.h> 65#include <sys/bus.h> 66#include <sys/kernel.h> 67#include <sys/libkern.h> 68#include <sys/module.h> 69 |
70#include <machine/vm86.h> | 70#include <vm/vm.h> 71#include <vm/pmap.h> |
71 | 72 |
73#include <contrib/x86emu/x86emu.h> 74#include <contrib/x86emu/x86emu_regs.h> 75 |
|
72/* 73 * VESA DPMS States 74 */ 75#define DPMS_ON 0x00 76#define DPMS_STANDBY 0x01 77#define DPMS_SUSPEND 0x02 78#define DPMS_OFF 0x04 79#define DPMS_REDUCEDON 0x08 --- 5 unchanged lines hidden (view full) --- 85#define VBE_MAJORVERSION_MASK 0x0F 86#define VBE_MINORVERSION_MASK 0xF0 87 88struct dpms_softc { 89 int dpms_supported_states; 90 int dpms_initial_state; 91}; 92 | 76/* 77 * VESA DPMS States 78 */ 79#define DPMS_ON 0x00 80#define DPMS_STANDBY 0x01 81#define DPMS_SUSPEND 0x02 82#define DPMS_OFF 0x04 83#define DPMS_REDUCEDON 0x08 --- 5 unchanged lines hidden (view full) --- 89#define VBE_MAJORVERSION_MASK 0x0F 90#define VBE_MINORVERSION_MASK 0xF0 91 92struct dpms_softc { 93 int dpms_supported_states; 94 int dpms_initial_state; 95}; 96 |
97static struct x86emu vesa_emu; 98static unsigned char *emumem = NULL; 99 |
|
93static int dpms_attach(device_t); 94static int dpms_detach(device_t); 95static int dpms_get_supported_states(int *); 96static int dpms_get_current_state(int *); 97static void dpms_identify(driver_t *, device_t); 98static int dpms_probe(device_t); 99static int dpms_resume(device_t); 100static int dpms_set_state(int); --- 13 unchanged lines hidden (view full) --- 114 "dpms", 115 dpms_methods, 116 sizeof(struct dpms_softc), 117}; 118 119static devclass_t dpms_devclass; 120 121DRIVER_MODULE(dpms, vgapci, dpms_driver, dpms_devclass, NULL, NULL); | 100static int dpms_attach(device_t); 101static int dpms_detach(device_t); 102static int dpms_get_supported_states(int *); 103static int dpms_get_current_state(int *); 104static void dpms_identify(driver_t *, device_t); 105static int dpms_probe(device_t); 106static int dpms_resume(device_t); 107static int dpms_set_state(int); --- 13 unchanged lines hidden (view full) --- 121 "dpms", 122 dpms_methods, 123 sizeof(struct dpms_softc), 124}; 125 126static devclass_t dpms_devclass; 127 128DRIVER_MODULE(dpms, vgapci, dpms_driver, dpms_devclass, NULL, NULL); |
129MODULE_DEPEND(dpms, x86emu, 1, 1, 1); |
|
122 | 130 |
131static uint8_t 132vm86_emu_inb(struct x86emu *emu, uint16_t port) 133{ 134 if (port == 0xb2) /* APM scratch register */ 135 return 0; 136 if (port >= 0x80 && port < 0x88) /* POST status register */ 137 return 0; 138 return inb(port); 139} 140 141static uint16_t 142vm86_emu_inw(struct x86emu *emu, uint16_t port) 143{ 144 if (port >= 0x80 && port < 0x88) /* POST status register */ 145 return 0; 146 return inw(port); 147} 148 149static uint32_t 150vm86_emu_inl(struct x86emu *emu, uint16_t port) 151{ 152 if (port >= 0x80 && port < 0x88) /* POST status register */ 153 return 0; 154 return inl(port); 155} 156 |
|
123static void | 157static void |
158vm86_emu_outb(struct x86emu *emu, uint16_t port, uint8_t val) 159{ 160 if (port == 0xb2) /* APM scratch register */ 161 return; 162 if (port >= 0x80 && port < 0x88) /* POST status register */ 163 return; 164 outb(port, val); 165} 166 167static void 168vm86_emu_outw(struct x86emu *emu, uint16_t port, uint16_t val) 169{ 170 if (port >= 0x80 && port < 0x88) /* POST status register */ 171 return; 172 outw(port, val); 173} 174 175static void 176vm86_emu_outl(struct x86emu *emu, uint16_t port, uint32_t val) 177{ 178 if (port >= 0x80 && port < 0x88) /* POST status register */ 179 return; 180 outl(port, val); 181} 182 183static void |
|
124dpms_identify(driver_t *driver, device_t parent) 125{ 126 127 /* 128 * XXX: The DPMS VBE only allows for manipulating a single 129 * monitor, but we don't know which one. Just attach to the 130 * first vgapci(4) device we encounter and hope it is the 131 * right one. 132 */ 133 if (devclass_get_device(dpms_devclass, 0) == NULL) 134 device_add_child(parent, "dpms", 0); | 184dpms_identify(driver_t *driver, device_t parent) 185{ 186 187 /* 188 * XXX: The DPMS VBE only allows for manipulating a single 189 * monitor, but we don't know which one. Just attach to the 190 * first vgapci(4) device we encounter and hope it is the 191 * right one. 192 */ 193 if (devclass_get_device(dpms_devclass, 0) == NULL) 194 device_add_child(parent, "dpms", 0); |
195 |
|
135} 136 137static int 138dpms_probe(device_t dev) 139{ 140 int error, states; 141 | 196} 197 198static int 199dpms_probe(device_t dev) 200{ 201 int error, states; 202 |
203 emumem = pmap_mapbios(0x0, 0xc00000); 204 205 memset(&vesa_emu, 0, sizeof(vesa_emu)); 206 x86emu_init_default(&vesa_emu); 207 208 vesa_emu.emu_inb = vm86_emu_inb; 209 vesa_emu.emu_inw = vm86_emu_inw; 210 vesa_emu.emu_inl = vm86_emu_inl; 211 vesa_emu.emu_outb = vm86_emu_outb; 212 vesa_emu.emu_outw = vm86_emu_outw; 213 vesa_emu.emu_outl = vm86_emu_outl; 214 215 vesa_emu.mem_base = (char *)emumem; 216 vesa_emu.mem_size = 1024 * 1024; 217 |
|
142 error = dpms_get_supported_states(&states); 143 if (error) 144 return (error); 145 device_set_desc(dev, "DPMS suspend/resume"); 146 device_quiet(dev); 147 return (BUS_PROBE_DEFAULT); 148} 149 --- 9 unchanged lines hidden (view full) --- 159 return (error); 160 error = dpms_get_current_state(&sc->dpms_initial_state); 161 return (error); 162} 163 164static int 165dpms_detach(device_t dev) 166{ | 218 error = dpms_get_supported_states(&states); 219 if (error) 220 return (error); 221 device_set_desc(dev, "DPMS suspend/resume"); 222 device_quiet(dev); 223 return (BUS_PROBE_DEFAULT); 224} 225 --- 9 unchanged lines hidden (view full) --- 235 return (error); 236 error = dpms_get_current_state(&sc->dpms_initial_state); 237 return (error); 238} 239 240static int 241dpms_detach(device_t dev) 242{ |
243 if (emumem) 244 pmap_unmapdev((vm_offset_t)emumem, 0xc00000); |
|
167 168 return (0); 169} 170 171static int 172dpms_suspend(device_t dev) 173{ 174 --- 9 unchanged lines hidden (view full) --- 184 sc = device_get_softc(dev); 185 dpms_set_state(sc->dpms_initial_state); 186 return (0); 187} 188 189static int 190dpms_call_bios(int subfunction, int *bh) 191{ | 245 246 return (0); 247} 248 249static int 250dpms_suspend(device_t dev) 251{ 252 --- 9 unchanged lines hidden (view full) --- 262 sc = device_get_softc(dev); 263 dpms_set_state(sc->dpms_initial_state); 264 return (0); 265} 266 267static int 268dpms_call_bios(int subfunction, int *bh) 269{ |
192 struct vm86frame vmf; 193 int error; | 270 vesa_emu.x86.R_AX = VBE_DPMS_FUNCTION; 271 vesa_emu.x86.R_BL = subfunction; 272 vesa_emu.x86.R_BH = *bh; 273 vesa_emu.x86.R_ES = 0; 274 vesa_emu.x86.R_DI = 0; 275 x86emu_exec_intr(&vesa_emu, 0x10); |
194 | 276 |
195 bzero(&vmf, sizeof(vmf)); 196 vmf.vmf_ax = VBE_DPMS_FUNCTION; 197 vmf.vmf_bl = subfunction; 198 vmf.vmf_bh = *bh; 199 vmf.vmf_es = 0; 200 vmf.vmf_di = 0; 201 error = vm86_intcall(0x10, &vmf); 202 if (error == 0 && (vmf.vmf_eax & 0xffff) != 0x004f) 203 error = ENXIO; 204 if (error == 0) 205 *bh = vmf.vmf_bh; 206 return (error); | 277 if ((vesa_emu.x86.R_EAX & 0xffff) != 0x004f) 278 return (ENXIO); 279 280 *bh = vesa_emu.x86.R_BH; 281 282 return (0); |
207} 208 209static int 210dpms_get_supported_states(int *states) 211{ 212 213 *states = 0; 214 return (dpms_call_bios(VBE_DPMS_GET_SUPPORTED_STATES, states)); --- 16 unchanged lines hidden --- | 283} 284 285static int 286dpms_get_supported_states(int *states) 287{ 288 289 *states = 0; 290 return (dpms_call_bios(VBE_DPMS_GET_SUPPORTED_STATES, states)); --- 16 unchanged lines hidden --- |