aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/fb
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2009-10-19 20:58:10 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2009-10-19 20:58:10 +0000
commit3219f535d98ad7c1a1b731f022c7b9ec4402094c (patch)
treed4a62e4e5d88debc2e3a4761c8ceea077f9a2ac1 /sys/dev/fb
parent72c042dfb56fec9f2f29177367688e0a77c6e210 (diff)
downloadsrc-3219f535d98ad7c1a1b731f022c7b9ec4402094c.tar.gz
src-3219f535d98ad7c1a1b731f022c7b9ec4402094c.zip
Rewrite x86bios and update its dependent drivers.
- Do not map entire real mode memory (1MB). Instead, we map IVT/BDA and ROM area separately. Most notably, ROM area is mapped as device memory (uncacheable) as it should be. User memory is dynamically allocated and free'ed with contigmalloc(9) and contigfree(9). Remove now redundant and potentially dangerous x86bios_alloc.c. If this emulator ever grows to support non-PC hardware, we may implement it with rman(9) later. - Move all host-specific initializations from x86emu_util.c to x86bios.c and remove now unnecessary x86emu_util.c. Currently, non-PC hardware is not supported. We may use bus_space(9) later when the KPI is fixed. - Replace all bzero() calls for emulated registers with more obviously named x86bios_init_regs(). This function also initializes DS and SS properly. - Add x86bios_get_intr(). This function checks if the interrupt vector is available for the platform. It is not necessary for PC-compatible hardware but it may be needed later. ;-) - Do not try turning off monitor if DPMS does not support the state. - Allocate stable memory for VESA OEM strings instead of just holding pointers to them. They may or may not be accessible always. Fix a memory leak of video mode table while I am here. - Add (experimental) BIOS POST call for vesa(4). This function calls VGA BIOS POST code from the current VGA option ROM. Some video controllers cannot save and restore the state properly even if it is claimed to be supported. Usually the symptom is blank display after resuming from suspend state. If the video mode does not match the previous mode after restoring, we try BIOS POST and force the known good initial state. Some magic was taken from NetBSD (and it was taken from vbetool, I believe.) - Add a loader tunable for vgapci(4) to give a hint to dpms(4) and vesa(4) to identify who owns the VESA BIOS. This is very useful for multi-display adapter setup. By default, the POST video controller is automatically probed and the tunable "hw.pci.default_vgapci_unit" is set to corresponding vgapci unit number. You may override it from loader but it is very unlikely to be necessary. Unfortunately only AGP/PCI/PCI-E controllers can be matched because ISA controller does not have necessary device IDs. - Fix a long standing bug in state save/restore function. The state buffer pointer should be ES:BX, not ES:DI according to VBE 3.0. If it ever worked, that's because BX was always zero. :-) - Clean up register initializations more clearer per VBE 3.0. - Fix a lot of style issues with vesa(4).
Notes
Notes: svn path=/head/; revision=198251
Diffstat (limited to 'sys/dev/fb')
-rw-r--r--sys/dev/fb/vesa.c794
1 files changed, 490 insertions, 304 deletions
diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c
index 8a6136828661..11b95985d7d9 100644
--- a/sys/dev/fb/vesa.c
+++ b/sys/dev/fb/vesa.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#ifndef VGA_NO_MODE_CHANGE
#include <sys/param.h>
+#include <sys/bus.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
@@ -51,6 +52,8 @@ __FBSDID("$FreeBSD$");
#include <dev/fb/fbreg.h>
#include <dev/fb/vgareg.h>
+#include <dev/pci/pcivar.h>
+
#include <isa/isareg.h>
#include <compat/x86bios/x86bios.h>
@@ -160,7 +163,9 @@ static char *vesa_revstr = NULL;
#define BIOS_SADDRTOLADDR(p) ((((p) & 0xffff0000) >> 12) + ((p) & 0x0000ffff))
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);
@@ -222,12 +227,62 @@ int10_set_mode(int mode)
{
x86regs_t regs;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x0000 | mode;
+ x86bios_init_regs(&regs);
+ regs.R_AL = mode;
x86bios_intr(&regs, 0x10);
- return 0;
+ return (0);
+}
+
+static int
+vesa_bios_post(void)
+{
+ x86regs_t regs;
+ devclass_t dc;
+ device_t *devs;
+ device_t dev;
+ int count, i, is_pci;
+
+ if (x86bios_get_orm(0xc0000) == NULL)
+ return (1);
+
+ dev = NULL;
+ is_pci = 0;
+
+ /* Find the matching PCI video controller. */
+ dc = devclass_find("vgapci");
+ if (dc != NULL && devclass_get_devices(dc, &devs, &count) == 0) {
+ for (dev = NULL, i = 0; dev == NULL && i < count; devs++, i++)
+ if (x86bios_match_device(0xc0000, *devs) &&
+ device_get_flags(*devs) != 0) {
+ dev = *devs;
+ is_pci = 1;
+ break;
+ }
+ free(devs, M_TEMP);
+ }
+
+ /* Try VGA if a PCI device is not found. */
+ if (dev == NULL) {
+ dc = devclass_find(VGA_DRIVER_NAME);
+ if (dc != NULL)
+ dev = devclass_get_device(dc, 0);
+ }
+
+ if (bootverbose)
+ printf("%s: calling BIOS POST\n",
+ dev == NULL ? "VESA" : device_get_nameunit(dev));
+
+ x86bios_init_regs(&regs);
+ if (is_pci) {
+ regs.R_AH = pci_get_bus(dev);
+ regs.R_AL = (pci_get_slot(dev) << 3) |
+ (pci_get_function(dev) & 0x07);
+ }
+ regs.R_DL = 0x80;
+ x86bios_call(&regs, 0xc000, 0x0003);
+ return (0);
}
/* VESA BIOS calls */
@@ -235,30 +290,47 @@ static int
vesa_bios_get_mode(int mode, struct vesa_mode *vmode)
{
x86regs_t regs;
- int offs;
- u_char *buf;
+ uint32_t offs;
+ void *buf;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f01;
- regs.R_ECX = mode;
+ buf = x86bios_alloc(&offs, sizeof(*vmode));
+ if (buf == NULL)
+ return (1);
- buf = (u_char *)x86bios_alloc(1, &offs);
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f01;
+ regs.R_CX = mode;
- regs.R_ES = SEG_ADDR(offs);
- regs.R_DI = SEG_OFF(offs);
+ regs.R_ES = X86BIOS_PHYSTOSEG(offs);
+ regs.R_DI = X86BIOS_PHYSTOOFF(offs);
x86bios_intr(&regs, 0x10);
- if ((regs.R_AX & 0xff) != 0x4f)
- {
- x86bios_free(buf, 1);
- return 1;
+ if (regs.R_AX != 0x004f) {
+ x86bios_free(buf, sizeof(*vmode));
+ return (1);
}
bcopy(buf, vmode, sizeof(*vmode));
- x86bios_free(buf, 1);
+ x86bios_free(buf, sizeof(*vmode));
- return 0;
+ return (0);
+}
+
+static int
+vesa_bios_get_current_mode(void)
+{
+ x86regs_t regs;
+
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f03;
+
+ x86bios_intr(&regs, 0x10);
+
+ if (regs.R_AX != 0x004f)
+ return (-1);
+
+ return (regs.R_BX);
}
static int
@@ -266,13 +338,13 @@ vesa_bios_set_mode(int mode)
{
x86regs_t regs;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f02;
- regs.R_EBX = mode;
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f02;
+ regs.R_BX = mode;
x86bios_intr(&regs, 0x10);
- return ((regs.R_AX & 0xff) != 0x4f);
+ return (regs.R_AX != 0x004f);
}
static int
@@ -280,16 +352,16 @@ vesa_bios_get_dac(void)
{
x86regs_t regs;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f08;
- regs.R_EBX = 1;
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f08;
+ regs.R_BL = 1;
x86bios_intr(&regs, 0x10);
- if ((regs.R_AX & 0xff) != 0x4f)
- return 6;
+ if (regs.R_AX != 0x004f)
+ return (6);
- return ((regs.R_EBX >> 8) & 0x00ff);
+ return (regs.R_BH);
}
static int
@@ -297,43 +369,45 @@ vesa_bios_set_dac(int bits)
{
x86regs_t regs;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f08;
- regs.R_EBX = (bits << 8);
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f08;
+ /* regs.R_BL = 0; */
+ regs.R_BH = bits;
x86bios_intr(&regs, 0x10);
- if ((regs.R_AX & 0xff) != 0x4f)
- return 6;
+ if (regs.R_AX != 0x004f)
+ return (6);
- return ((regs.R_EBX >> 8) & 0x00ff);
+ return (regs.R_BH);
}
static int
vesa_bios_save_palette(int start, int colors, u_char *palette, int bits)
{
x86regs_t regs;
- int offs;
+ uint32_t offs;
u_char *p;
int i;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f09;
- regs.R_EBX = 1;
- regs.R_ECX = colors;
- regs.R_EDX = start;
+ p = (u_char *)x86bios_alloc(&offs, colors * 4);
+ if (p == NULL)
+ return (1);
- p = (u_char *)x86bios_alloc(1, &offs);
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f09;
+ regs.R_BL = 1;
+ regs.R_CX = colors;
+ regs.R_DX = start;
- regs.R_ES = SEG_ADDR(offs);
- regs.R_DI = SEG_OFF(offs);
+ regs.R_ES = X86BIOS_PHYSTOSEG(offs);
+ regs.R_DI = X86BIOS_PHYSTOOFF(offs);
x86bios_intr(&regs, 0x10);
- if ((regs.R_AX & 0xff) != 0x4f)
- {
- x86bios_free(p, 1);
- return 1;
+ if (regs.R_AX != 0x004f) {
+ x86bios_free(p, colors * 4);
+ return (1);
}
bits = 8 - bits;
@@ -342,9 +416,9 @@ vesa_bios_save_palette(int start, int colors, u_char *palette, int bits)
palette[i*3 + 1] = p[i*4 + 1] << bits;
palette[i*3 + 2] = p[i*4] << bits;
}
+ x86bios_free(p, colors * 4);
- x86bios_free(p, 1);
- return 0;
+ return (0);
}
static int
@@ -352,27 +426,28 @@ vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
int bits)
{
x86regs_t regs;
- int offs;
+ uint32_t offs;
u_char *p;
int i;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f09;
- regs.R_EBX = 1;
- regs.R_ECX = colors;
- regs.R_EDX = start;
+ p = (u_char *)x86bios_alloc(&offs, colors * 4);
+ if (p == NULL)
+ return (1);
- p = (u_char *)x86bios_alloc(1, &offs);
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f09;
+ regs.R_BL = 1;
+ regs.R_CX = colors;
+ regs.R_DX = start;
- regs.R_ES = SEG_ADDR(offs);
- regs.R_DI = SEG_OFF(offs);
+ regs.R_ES = X86BIOS_PHYSTOSEG(offs);
+ regs.R_DI = X86BIOS_PHYSTOOFF(offs);
x86bios_intr(&regs, 0x10);
- if ((regs.R_AX & 0xff) != 0x4f)
- {
- x86bios_free(p, 1);
- return 1;
+ if (regs.R_AX != 0x004f) {
+ x86bios_free(p, colors * 4);
+ return (1);
}
bits = 8 - bits;
@@ -381,20 +456,31 @@ vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
g[i] = p[i*4 + 1] << bits;
b[i] = p[i*4] << bits;
}
+ x86bios_free(p, colors * 4);
- x86bios_free(p, 1);
- return 0;
+ return (0);
}
static int
vesa_bios_load_palette(int start, int colors, u_char *palette, int bits)
{
x86regs_t regs;
- int offs;
+ uint32_t offs;
u_char *p;
int i;
- p = (u_char *)x86bios_alloc(1, &offs);
+ p = (u_char *)x86bios_alloc(&offs, colors * 4);
+ if (p == NULL)
+ return (1);
+
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f09;
+ /* regs.R_BL = 0; */
+ regs.R_CX = colors;
+ regs.R_DX = start;
+
+ regs.R_ES = X86BIOS_PHYSTOSEG(offs);
+ regs.R_DI = X86BIOS_PHYSTOOFF(offs);
bits = 8 - bits;
for (i = 0; i < colors; ++i) {
@@ -403,21 +489,10 @@ vesa_bios_load_palette(int start, int colors, u_char *palette, int bits)
p[i*4 + 2] = palette[i*3] >> bits;
p[i*4 + 3] = 0;
}
-
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f09;
- regs.R_EBX = 0;
- regs.R_ECX = colors;
- regs.R_EDX = start;
-
- regs.R_ES = SEG_ADDR(offs);
- regs.R_DI = SEG_OFF(offs);
-
x86bios_intr(&regs, 0x10);
+ x86bios_free(p, colors * 4);
- x86bios_free(p, 1);
-
- return ((regs.R_AX & 0xff) != 0x4f);
+ return (regs.R_AX != 0x004f);
}
#ifdef notyet
@@ -426,11 +501,22 @@ vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
int bits)
{
x86regs_t regs;
- int offs;
+ uint32_t offs;
u_char *p;
int i;
- p = (u_char *)x86bios_alloc(1, &offs);
+ p = (u_char *)x86bios_alloc(&offs, colors * 4);
+ if (p == NULL)
+ return (1);
+
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f09;
+ /* regs.R_BL = 0; */
+ regs.R_CX = colors;
+ regs.R_DX = start;
+
+ regs.R_ES = X86BIOS_PHYSTOSEG(offs);
+ regs.R_DI = X86BIOS_PHYSTOOFF(offs);
bits = 8 - bits;
for (i = 0; i < colors; ++i) {
@@ -439,21 +525,10 @@ vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
p[i*4 + 2] = r[i] >> bits;
p[i*4 + 3] = 0;
}
-
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f09;
- regs.R_EBX = 0;
- regs.R_ECX = colors;
- regs.R_EDX = start;
-
- regs.R_ES = SEG_ADDR(offs);
- regs.R_DI = SEG_OFF(offs);
-
x86bios_intr(&regs, 0x10);
+ x86bios_free(p, colors * 4);
- x86bios_free(p, 1);
-
- return ((regs.R_AX & 0xff) != 0x4f);
+ return (regs.R_AX != 0x004f);
}
#endif
@@ -462,48 +537,55 @@ vesa_bios_state_buf_size(void)
{
x86regs_t regs;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f04;
- regs.R_ECX = STATE_ALL;
- regs.R_EDX = STATE_SIZE;
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f04;
+ /* regs.R_DL = STATE_SIZE; */
+ regs.R_CX = STATE_ALL;
x86bios_intr(&regs, 0x10);
- if ((regs.R_AX & 0xff) != 0x4f)
- return 0;
+ if (regs.R_AX != 0x004f)
+ return (0);
- return regs.R_BX * 64;
+ return (regs.R_BX * 64);
}
static int
vesa_bios_save_restore(int code, void *p, size_t size)
{
x86regs_t regs;
- int offs;
- u_char *buf;
+ uint32_t offs;
+ void *buf;
if (size > VESA_BIOS_BUFSIZE)
return (1);
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f04;
- regs.R_ECX = STATE_ALL;
- regs.R_EDX = code;
-
- buf = (u_char *)x86bios_alloc(1, &offs);
-
- regs.R_ES = SEG_ADDR(offs);
- regs.R_DI = SEG_OFF(offs);
-
- bcopy(p, buf, size);
-
- x86bios_intr(&regs, 0x10);
-
- bcopy(buf, p, size);
+ if (code != STATE_SAVE && code != STATE_LOAD)
+ return (1);
- x86bios_free(p, 1);
+ buf = x86bios_alloc(&offs, size);
+
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f04;
+ regs.R_DL = code;
+ regs.R_CX = STATE_ALL;
+
+ regs.R_ES = X86BIOS_PHYSTOSEG(offs);
+ regs.R_BX = X86BIOS_PHYSTOOFF(offs);
+
+ switch (code) {
+ case STATE_SAVE:
+ x86bios_intr(&regs, 0x10);
+ bcopy(buf, p, size);
+ break;
+ case STATE_LOAD:
+ bcopy(p, buf, size);
+ x86bios_intr(&regs, 0x10);
+ break;
+ }
+ x86bios_free(buf, size);
- return ((regs.R_AX & 0xff) != 0x4f);
+ return (regs.R_AX != 0x004f);
}
static int
@@ -511,16 +593,16 @@ vesa_bios_get_line_length(void)
{
x86regs_t regs;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f06;
- regs.R_EBX = 1;
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f06;
+ regs.R_BL = 1;
x86bios_intr(&regs, 0x10);
- if ((regs.R_AX & 0xff) != 0x4f)
- return -1;
+ if (regs.R_AX != 0x004f)
+ return (-1);
- return regs.R_BX;
+ return (regs.R_BX);
}
static int
@@ -528,25 +610,25 @@ vesa_bios_set_line_length(int pixel, int *bytes, int *lines)
{
x86regs_t regs;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f06;
- regs.R_EBX = 0;
- regs.R_ECX = pixel;
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f06;
+ /* regs.R_BL = 0; */
+ regs.R_CX = pixel;
x86bios_intr(&regs, 0x10);
#if VESA_DEBUG > 1
printf("bx:%d, cx:%d, dx:%d\n", regs.R_BX, regs.R_CX, regs.R_DX);
#endif
- if ((regs.R_AX & 0xff) != 0x4f)
- return -1;
+ if (regs.R_AX != 0x004f)
+ return (-1);
- if (bytes)
+ if (bytes != NULL)
*bytes = regs.R_BX;
- if (lines)
+ if (lines != NULL)
*lines = regs.R_DX;
- return 0;
+ return (0);
}
#if 0
@@ -555,19 +637,19 @@ vesa_bios_get_start(int *x, int *y)
{
x86regs_t regs;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f07;
- regs.R_EBX = 1;
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f07;
+ regs.R_BL = 1;
x86bios_intr(&regs, 0x10);
- if ((regs.R_AX & 0xff) != 0x4f)
- return -1;
+ if (regs.R_AX != 0x004f)
+ return (-1);
*x = regs.R_CX;
*y = regs.R_DX;
- return 0;
+ return (0);
}
#endif
@@ -576,15 +658,15 @@ vesa_bios_set_start(int x, int y)
{
x86regs_t regs;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f07;
- regs.R_EBX = 0x80;
- regs.R_EDX = y;
- regs.R_ECX = x;
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f07;
+ regs.R_BL = 0x80;
+ regs.R_CX = x;
+ regs.R_DX = y;
x86bios_intr(&regs, 0x10);
- return ((regs.R_AX & 0xff) != 0x4f);
+ return (regs.R_AX != 0x004f);
}
/* map a generic video mode to a known mode */
@@ -604,9 +686,9 @@ vesa_map_gen_mode_num(int type, int color, int mode)
for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
if (mode_map[i].from == mode)
- return mode_map[i].to;
+ return (mode_map[i].to);
}
- return mode;
+ return (mode);
}
static int
@@ -628,7 +710,7 @@ vesa_translate_flags(u_int16_t vflags)
flags |= (vflags & ftable[i].mask) ?
ftable[i].set : ftable[i].reset;
}
- return flags;
+ return (flags);
}
static int
@@ -649,9 +731,9 @@ vesa_translate_mmodel(u_int8_t vmodel)
for (i = 0; mtable[i].mmodel >= 0; ++i) {
if (mtable[i].vmodel == vmodel)
- return mtable[i].mmodel;
+ return (mtable[i].mmodel);
}
- return V_INFO_MM_OTHER;
+ return (V_INFO_MM_OTHER);
}
static int
@@ -685,6 +767,18 @@ vesa_get_line_width(video_info_t *info)
return (len > 0 ? len : width);
}
+#define VESA_MAXSTR 256
+
+#define VESA_STRCPY(dst, src) do { \
+ char *str; \
+ int i; \
+ dst = malloc(VESA_MAXSTR, M_DEVBUF, M_WAITOK); \
+ str = x86bios_offset(BIOS_SADDRTOLADDR(src)); \
+ for (i = 0; i < VESA_MAXSTR - 1 && str[i] != '\0'; i++) \
+ dst[i] = str[i]; \
+ dst[i] = '\0'; \
+} while (0)
+
static int
vesa_bios_init(void)
{
@@ -693,32 +787,50 @@ vesa_bios_init(void)
video_info_t *p;
x86regs_t regs;
size_t bsize;
- int offs;
- u_char *vmbuf;
+ void *vmbuf;
+ uint32_t offs;
+ uint16_t vers;
int is_via_cle266;
int modes;
int i;
if (vesa_init_done)
- return 0;
+ return (0);
has_vesa_bios = FALSE;
vesa_adp_info = NULL;
vesa_vmode_max = 0;
vesa_vmode[0].vi_mode = EOT;
- vmbuf = (u_char *)x86bios_alloc(1, &offs);
- bcopy("VBE2", vmbuf, 4); /* try for VBE2 data */
+ /*
+ * If the VBE real mode interrupt vector is not found, try BIOS POST.
+ */
+ if (x86bios_get_intr(0x10) == 0) {
+ if (vesa_bios_post() != 0)
+ return (1);
+ offs = x86bios_get_intr(0x10);
+ if (offs == 0)
+ return (1);
+ if (bootverbose)
+ printf("VESA: interrupt vector installed (0x%x)\n",
+ BIOS_SADDRTOLADDR(offs));
+ }
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f00;
- regs.R_ES = SEG_ADDR(offs);
- regs.R_DI = SEG_OFF(offs);
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f00;
+ vmbuf = x86bios_alloc(&offs, sizeof(buf));
+ if (vmbuf == NULL)
+ return (1);
+
+ regs.R_ES = X86BIOS_PHYSTOSEG(offs);
+ regs.R_DI = X86BIOS_PHYSTOOFF(offs);
+
+ bcopy("VBE2", vmbuf, 4); /* try for VBE2 data */
x86bios_intr(&regs, 0x10);
- if (((regs.R_AX & 0xff) != 0x4f) || bcmp("VESA", vmbuf, 4))
- return 1;
+ if (regs.R_AX != 0x004f || bcmp("VESA", vmbuf, 4) != 0)
+ goto fail;
bcopy(vmbuf, &buf, sizeof(buf));
@@ -727,34 +839,43 @@ vesa_bios_init(void)
printf("VESA: information block\n");
dump_buffer((u_char *)&buf, sizeof(buf));
}
- if (vesa_adp_info->v_version < 0x0102) {
+
+ vers = buf.v_version = le16toh(buf.v_version);
+ buf.v_oemstr = le32toh(buf.v_oemstr);
+ buf.v_flags = le32toh(buf.v_flags);
+ buf.v_modetable = le32toh(buf.v_modetable);
+ buf.v_memsize = le16toh(buf.v_memsize);
+ buf.v_revision = le16toh(buf.v_revision);
+ buf.v_venderstr = le32toh(buf.v_venderstr);
+ buf.v_prodstr = le32toh(buf.v_prodstr);
+ buf.v_revstr = le32toh(buf.v_revstr);
+
+ if (vers < 0x0102) {
printf("VESA: VBE version %d.%d is not supported; "
"version 1.2 or later is required.\n",
- ((vesa_adp_info->v_version & 0xf000) >> 12) * 10
- + ((vesa_adp_info->v_version & 0x0f00) >> 8),
- ((vesa_adp_info->v_version & 0x00f0) >> 4) * 10
- + (vesa_adp_info->v_version & 0x000f));
- return 1;
+ ((vers & 0xf000) >> 12) * 10 + ((vers & 0x0f00) >> 8),
+ ((vers & 0x00f0) >> 4) * 10 + (vers & 0x000f));
+ return (1);
}
- vesa_oemstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_oemstr));
-
- is_via_cle266 = strcmp(vesa_oemstr, VESA_VIA_CLE266) == 0;
-
- if (vesa_adp_info->v_version >= 0x0200) {
- vesa_venderstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_venderstr));
- vesa_prodstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_prodstr));
- vesa_revstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_revstr));
+ VESA_STRCPY(vesa_oemstr, buf.v_oemstr);
+ if (vers >= 0x0200) {
+ VESA_STRCPY(vesa_venderstr, buf.v_venderstr);
+ VESA_STRCPY(vesa_prodstr, buf.v_prodstr);
+ VESA_STRCPY(vesa_revstr, buf.v_revstr);
}
+ is_via_cle266 = strncmp(vesa_oemstr, VESA_VIA_CLE266,
+ sizeof(VESA_VIA_CLE266)) == 0;
- vesa_vmodetab = (uint16_t *)x86bios_offset(FARP(vesa_adp_info->v_modetable));
+ if (buf.v_modetable == 0)
+ goto fail;
- if (vesa_vmodetab == NULL)
- return 1;
+ vesa_vmodetab = x86bios_offset(BIOS_SADDRTOLADDR(buf.v_modetable));
for (i = 0, modes = 0;
(i < (M_VESA_MODE_MAX - M_VESA_BASE + 1))
&& (vesa_vmodetab[i] != 0xffff); ++i) {
+ vesa_vmodetab[i] = le16toh(vesa_vmodetab[i]);
if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode))
continue;
@@ -888,16 +1009,36 @@ vesa_bios_init(void)
}
vesa_vmode[modes].vi_mode = EOT;
- x86bios_free(vmbuf, 1);
-
if (bootverbose)
printf("VESA: %d mode(s) found\n", modes);
has_vesa_bios = (modes > 0);
if (!has_vesa_bios)
- return (1);
+ goto fail;
+ x86bios_free(vmbuf, sizeof(buf));
return (0);
+
+fail:
+ if (vmbuf != NULL)
+ x86bios_free(vmbuf, sizeof(buf));
+ if (vesa_oemstr != NULL) {
+ free(vesa_oemstr, M_DEVBUF);
+ vesa_oemstr = NULL;
+ }
+ if (vesa_venderstr != NULL) {
+ free(vesa_venderstr, M_DEVBUF);
+ vesa_venderstr = NULL;
+ }
+ if (vesa_prodstr != NULL) {
+ free(vesa_prodstr, M_DEVBUF);
+ vesa_prodstr = NULL;
+ }
+ if (vesa_revstr != NULL) {
+ free(vesa_revstr, M_DEVBUF);
+ vesa_revstr = NULL;
+ }
+ return (1);
}
static void
@@ -946,9 +1087,9 @@ vesa_configure(int flags)
int i;
if (vesa_init_done)
- return 0;
+ return (0);
if (flags & VIO_PROBE_ONLY)
- return 0; /* XXX */
+ return (0);
/*
* If the VESA module has already been loaded, abort loading
@@ -956,10 +1097,11 @@ vesa_configure(int flags)
*/
for (i = 0; (adp = vid_get_adapter(i)) != NULL; ++i) {
if (adp->va_flags & V_ADP_VESA)
- return ENXIO;
+ return (ENXIO);
if (adp->va_type == KD_VGA)
break;
}
+
/*
* The VGA adapter is not found. This is because either
* 1) the VGA driver has not been initialized, or 2) the VGA card
@@ -968,7 +1110,7 @@ vesa_configure(int flags)
*/
if (adp == NULL) {
vga_sub_configure = vesa_configure;
- return ENODEV;
+ return (ENODEV);
}
/* count number of registered adapters */
@@ -980,7 +1122,7 @@ vesa_configure(int flags)
vesa_adp = adp;
if (vesa_bios_init()) {
vesa_adp = NULL;
- return ENXIO;
+ return (ENXIO);
}
vesa_adp->va_flags |= V_ADP_VESA;
@@ -997,36 +1139,40 @@ vesa_configure(int flags)
vesa_init_done = TRUE;
} else {
vesa_adp = NULL;
- return error;
+ return (error);
}
- return 0;
+ return (0);
}
#if 0
static int
vesa_nop(void)
{
- return 0;
+
+ return (0);
}
#endif
static int
vesa_error(void)
{
- return 1;
+
+ return (1);
}
static int
vesa_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
{
- return (*prevvidsw->probe)(unit, adpp, arg, flags);
+
+ return ((*prevvidsw->probe)(unit, adpp, arg, flags));
}
static int
vesa_init(int unit, video_adapter_t *adp, int flags)
{
- return (*prevvidsw->init)(unit, adp, flags);
+
+ return ((*prevvidsw->init)(unit, adp, flags));
}
static int
@@ -1035,10 +1181,10 @@ vesa_get_info(video_adapter_t *adp, int mode, video_info_t *info)
int i;
if ((*prevvidsw->get_info)(adp, mode, info) == 0)
- return 0;
+ return (0);
if (adp != vesa_adp)
- return 1;
+ return (1);
mode = vesa_map_gen_mode_num(vesa_adp->va_type,
vesa_adp->va_flags & V_ADP_COLOR, mode);
@@ -1047,10 +1193,10 @@ vesa_get_info(video_adapter_t *adp, int mode, video_info_t *info)
continue;
if (vesa_vmode[i].vi_mode == mode) {
*info = vesa_vmode[i];
- return 0;
+ return (0);
}
}
- return 1;
+ return (1);
}
static int
@@ -1059,9 +1205,9 @@ vesa_query_mode(video_adapter_t *adp, video_info_t *info)
int i;
if ((*prevvidsw->query_mode)(adp, info) == 0)
- return 0;
+ return (0);
if (adp != vesa_adp)
- return ENODEV;
+ return (ENODEV);
for (i = 0; vesa_vmode[i].vi_mode != EOT; ++i) {
if ((info->vi_width != 0)
@@ -1087,9 +1233,9 @@ vesa_query_mode(video_adapter_t *adp, video_info_t *info)
&& (info->vi_flags != vesa_vmode[i].vi_flags))
continue;
*info = vesa_vmode[i];
- return 0;
+ return (0);
}
- return ENODEV;
+ return (ENODEV);
}
static int
@@ -1098,7 +1244,7 @@ vesa_set_mode(video_adapter_t *adp, int mode)
video_info_t info;
if (adp != vesa_adp)
- return (*prevvidsw->set_mode)(adp, mode);
+ return ((*prevvidsw->set_mode)(adp, mode));
mode = vesa_map_gen_mode_num(adp->va_type,
adp->va_flags & V_ADP_COLOR, mode);
@@ -1129,11 +1275,11 @@ vesa_set_mode(video_adapter_t *adp, int mode)
/* we may not need to handle this mode after all... */
if ((*prevvidsw->set_mode)(adp, mode) == 0)
- return 0;
+ return (0);
/* is the new mode supported? */
if (vesa_get_info(adp, mode, &info))
- return 1;
+ return (1);
/* assert(VESA_MODE(mode)); */
#if VESA_DEBUG > 0
@@ -1144,7 +1290,7 @@ vesa_set_mode(video_adapter_t *adp, int mode)
info.vi_flags &= ~V_INFO_LINEAR;
if (vesa_bios_set_mode(mode | ((info.vi_flags & V_INFO_LINEAR) ? 0x4000 : 0)))
- return 1;
+ return (1);
if (adp->va_info.vi_flags & V_INFO_LINEAR)
vesa_unmap_buffer(adp->va_buffer,
@@ -1190,29 +1336,32 @@ vesa_set_mode(video_adapter_t *adp, int mode)
/* move hardware cursor out of the way */
(*vidsw[vesa_adp->va_index]->set_hw_cursor)(vesa_adp, -1, -1);
- return 0;
+ return (0);
}
static int
vesa_save_font(video_adapter_t *adp, int page, int fontsize, int fontwidth,
u_char *data, int ch, int count)
{
- return (*prevvidsw->save_font)(adp, page, fontsize, fontwidth, data,
- ch, count);
+
+ return ((*prevvidsw->save_font)(adp, page, fontsize, fontwidth, data,
+ ch, count));
}
static int
vesa_load_font(video_adapter_t *adp, int page, int fontsize, int fontwidth,
u_char *data, int ch, int count)
{
- return (*prevvidsw->load_font)(adp, page, fontsize, fontwidth, data,
- ch, count);
+
+ return ((*prevvidsw->load_font)(adp, page, fontsize, fontwidth, data,
+ ch, count));
}
static int
vesa_show_font(video_adapter_t *adp, int page)
{
- return (*prevvidsw->show_font)(adp, page);
+
+ return ((*prevvidsw->show_font)(adp, page));
}
static int
@@ -1226,12 +1375,12 @@ vesa_save_palette(video_adapter_t *adp, u_char *palette)
bits = vesa_bios_get_dac();
error = vesa_bios_save_palette(0, 256, palette, bits);
if (error == 0)
- return 0;
+ return (0);
if (bits != 6)
- return error;
+ return (error);
}
- return (*prevvidsw->save_palette)(adp, palette);
+ return ((*prevvidsw->save_palette)(adp, palette));
}
static int
@@ -1245,48 +1394,67 @@ vesa_load_palette(video_adapter_t *adp, u_char *palette)
&& VESA_MODE(adp->va_mode) && ((bits = vesa_bios_set_dac(8)) > 6)) {
error = vesa_bios_load_palette(0, 256, palette, bits);
if (error == 0)
- return 0;
+ return (0);
if (vesa_bios_set_dac(6) != 6)
- return 1;
+ return (1);
}
#endif /* notyet */
- return (*prevvidsw->load_palette)(adp, palette);
+ return ((*prevvidsw->load_palette)(adp, palette));
}
static int
vesa_set_border(video_adapter_t *adp, int color)
{
- return (*prevvidsw->set_border)(adp, color);
+
+ return ((*prevvidsw->set_border)(adp, color));
}
static int
vesa_save_state(video_adapter_t *adp, void *p, size_t size)
{
+
if (adp != vesa_adp)
- return (*prevvidsw->save_state)(adp, p, size);
+ return ((*prevvidsw->save_state)(adp, p, size));
if (vesa_state_buf_size == 0)
vesa_state_buf_size = vesa_bios_state_buf_size();
if (size == 0)
return (sizeof(int) + vesa_state_buf_size);
else if (size < (sizeof(int) + vesa_state_buf_size))
- return 1;
+ return (1);
((adp_state_t *)p)->sig = V_STATE_SIG;
bzero(((adp_state_t *)p)->regs, vesa_state_buf_size);
- return vesa_bios_save_restore(STATE_SAVE, ((adp_state_t *)p)->regs,
- vesa_state_buf_size);
+ return (vesa_bios_save_restore(STATE_SAVE, ((adp_state_t *)p)->regs,
+ vesa_state_buf_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);
+ return ((*prevvidsw->load_state)(adp, p));
- return vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs,
- vesa_state_buf_size);
+ ret = vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs,
+ vesa_state_buf_size);
+
+ /*
+ * If the current mode is not restored properly, try BIOS POST and
+ * force setting the mode.
+ */
+ flags = adp->va_info.vi_flags;
+ if (!(flags & V_INFO_GRAPHICS))
+ flags &= ~V_INFO_LINEAR;
+ mode = adp->va_mode | ((flags & V_INFO_LINEAR) ? 0x4000 : 0);
+ if (vesa_bios_get_current_mode() != mode && vesa_bios_post() == 0 &&
+ x86bios_get_intr(0x10) != 0) {
+ int10_set_mode(adp->va_initial_bios_mode);
+ vesa_bios_set_mode(mode);
+ }
+ return (ret);
}
#if 0
@@ -1295,17 +1463,17 @@ vesa_get_origin(video_adapter_t *adp, off_t *offset)
{
x86regs_t regs;
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f05;
- regs.R_EBX = 0x10;
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f05;
+ regs.R_BL = 0x10;
x86bios_intr(&regs, 0x10);
- if ((regs.R_AX & 0xff) != 0x4f)
- return 1;
+ if (regs.R_AX != 0x004f)
+ return (1);
*offset = regs.DX * adp->va_window_gran;
- return 0;
+ return (0);
}
#endif
@@ -1321,99 +1489,107 @@ vesa_set_origin(video_adapter_t *adp, off_t offset)
* detect error.
*/
if (adp != vesa_adp)
- return (*prevvidsw->set_win_org)(adp, offset);
+ return ((*prevvidsw->set_win_org)(adp, offset));
/* if this is a linear frame buffer, do nothing */
if (adp->va_info.vi_flags & V_INFO_LINEAR)
- return 0;
+ return (0);
/* XXX */
if (adp->va_window_gran == 0)
- return 1;
+ return (1);
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f05;
- regs.R_EBX = 0;
- regs.R_EDX = offset / adp->va_window_gran;
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f05;
+ regs.R_DX = offset / adp->va_window_gran;
+
x86bios_intr(&regs, 0x10);
- if ((regs.R_AX & 0xff) != 0x4f)
- return 1;
+ if (regs.R_AX != 0x004f)
+ return (1);
- bzero(&regs, sizeof(regs));
- regs.R_EAX = 0x4f05;
- regs.R_EBX = 1;
- regs.R_EDX = offset / adp->va_window_gran;
+ x86bios_init_regs(&regs);
+ regs.R_AX = 0x4f05;
+ regs.R_BL = 1;
+ regs.R_DX = offset / adp->va_window_gran;
x86bios_intr(&regs, 0x10);
adp->va_window_orig = (offset/adp->va_window_gran)*adp->va_window_gran;
- return 0; /* XXX */
+ return (0); /* XXX */
}
static int
vesa_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
{
- return (*prevvidsw->read_hw_cursor)(adp, col, row);
+
+ return ((*prevvidsw->read_hw_cursor)(adp, col, row));
}
static int
vesa_set_hw_cursor(video_adapter_t *adp, int col, int row)
{
- return (*prevvidsw->set_hw_cursor)(adp, col, row);
+
+ return ((*prevvidsw->set_hw_cursor)(adp, col, row));
}
static int
vesa_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
int celsize, int blink)
{
- return (*prevvidsw->set_hw_cursor_shape)(adp, base, height, celsize,
- blink);
+
+ return ((*prevvidsw->set_hw_cursor_shape)(adp, base, height, celsize,
+ blink));
}
static int
vesa_blank_display(video_adapter_t *adp, int mode)
{
+
/* XXX: use VESA DPMS */
- return (*prevvidsw->blank_display)(adp, mode);
+ return ((*prevvidsw->blank_display)(adp, mode));
}
static int
vesa_mmap(video_adapter_t *adp, vm_offset_t offset, vm_paddr_t *paddr,
int prot)
{
+
#if VESA_DEBUG > 0
printf("vesa_mmap(): window:0x%tx, buffer:0x%tx, offset:0x%tx\n",
adp->va_info.vi_window, adp->va_info.vi_buffer, offset);
#endif
- if ((adp == vesa_adp) && (adp->va_info.vi_flags & V_INFO_LINEAR)) {
+ if ((adp == vesa_adp) &&
+ (adp->va_info.vi_flags & V_INFO_LINEAR) != 0) {
/* va_window_size == va_buffer_size/vi_planes */
/* XXX: is this correct? */
if (offset > adp->va_window_size - PAGE_SIZE)
- return -1;
+ return (-1);
*paddr = adp->va_info.vi_buffer + offset;
- return 0;
- } else {
- return (*prevvidsw->mmap)(adp, offset, paddr, prot);
+ return (0);
}
+ return ((*prevvidsw->mmap)(adp, offset, paddr, prot));
}
static int
vesa_clear(video_adapter_t *adp)
{
- return (*prevvidsw->clear)(adp);
+
+ return ((*prevvidsw->clear)(adp));
}
static int
vesa_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
{
- return (*prevvidsw->fill_rect)(adp, val, x, y, cx, cy);
+
+ return ((*prevvidsw->fill_rect)(adp, val, x, y, cx, cy));
}
static int
vesa_bitblt(video_adapter_t *adp,...)
{
+
/* FIXME */
- return 1;
+ return (1);
}
static int
@@ -1427,15 +1603,15 @@ get_palette(video_adapter_t *adp, int base, int count,
int error;
if ((base < 0) || (base >= 256) || (count < 0) || (count > 256))
- return 1;
+ return (1);
if ((base + count) > 256)
- return 1;
+ return (1);
if (!(vesa_adp_info->v_flags & V_DAC8) || !VESA_MODE(adp->va_mode))
- return 1;
+ return (1);
bits = vesa_bios_get_dac();
if (bits <= 6)
- return 1;
+ return (1);
r = malloc(count*3, M_DEVBUF, M_WAITOK);
g = r + count;
@@ -1453,14 +1629,14 @@ get_palette(video_adapter_t *adp, int base, int count,
free(r, M_DEVBUF);
/* if error && bits != 6 at this point, we are in trouble... XXX */
- return error;
+ return (error);
}
static int
set_palette(video_adapter_t *adp, int base, int count,
u_char *red, u_char *green, u_char *blue, u_char *trans)
{
- return 1;
+ return (1);
#ifdef notyet
u_char *r;
u_char *g;
@@ -1469,10 +1645,10 @@ set_palette(video_adapter_t *adp, int base, int count,
int error;
if ((base < 0) || (base >= 256) || (base + count > 256))
- return 1;
+ return (1);
if (!(vesa_adp_info->v_flags & V_DAC8) || !VESA_MODE(adp->va_mode)
|| ((bits = vesa_bios_set_dac(8)) <= 6))
- return 1;
+ return (1);
r = malloc(count*3, M_DEVBUF, M_WAITOK);
g = r + count;
@@ -1484,11 +1660,11 @@ set_palette(video_adapter_t *adp, int base, int count,
error = vesa_bios_load_palette2(base, count, r, g, b, bits);
free(r, M_DEVBUF);
if (error == 0)
- return 0;
+ return (0);
/* if the following call fails, we are in trouble... XXX */
vesa_bios_set_dac(6);
- return 1;
+ return (1);
#endif /* notyet */
}
@@ -1498,7 +1674,7 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
int bytes;
if (adp != vesa_adp)
- return (*prevvidsw->ioctl)(adp, cmd, arg);
+ return ((*prevvidsw->ioctl)(adp, cmd, arg));
switch (cmd) {
case FBIO_SETWINORG: /* set frame buffer window origin */
@@ -1508,24 +1684,24 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
case FBIO_SETDISPSTART: /* set display start address */
if (!VESA_MODE(adp->va_mode))
- return (*prevvidsw->ioctl)(adp, cmd, arg);
+ return ((*prevvidsw->ioctl)(adp, cmd, arg));
if (vesa_bios_set_start(((video_display_start_t *)arg)->x,
((video_display_start_t *)arg)->y))
- return ENODEV;
+ return (ENODEV);
adp->va_disp_start.x = ((video_display_start_t *)arg)->x;
adp->va_disp_start.y = ((video_display_start_t *)arg)->y;
- return 0;
+ return (0);
case FBIO_SETLINEWIDTH: /* set line length in pixel */
if (!VESA_MODE(adp->va_mode))
- return (*prevvidsw->ioctl)(adp, cmd, arg);
+ return ((*prevvidsw->ioctl)(adp, cmd, arg));
if (vesa_bios_set_line_length(*(u_int *)arg, &bytes, NULL))
- return ENODEV;
+ return (ENODEV);
adp->va_line_width = bytes;
#if VESA_DEBUG > 1
printf("new line width:%d\n", adp->va_line_width);
#endif
- return 0;
+ return (0);
case FBIO_GETPALETTE: /* get color palette */
if (get_palette(adp, ((video_color_palette_t *)arg)->index,
@@ -1534,8 +1710,8 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
((video_color_palette_t *)arg)->green,
((video_color_palette_t *)arg)->blue,
((video_color_palette_t *)arg)->transparent))
- return (*prevvidsw->ioctl)(adp, cmd, arg);
- return 0;
+ return ((*prevvidsw->ioctl)(adp, cmd, arg));
+ return (0);
case FBIO_SETPALETTE: /* set color palette */
@@ -1545,8 +1721,8 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
((video_color_palette_t *)arg)->green,
((video_color_palette_t *)arg)->blue,
((video_color_palette_t *)arg)->transparent))
- return (*prevvidsw->ioctl)(adp, cmd, arg);
- return 0;
+ return ((*prevvidsw->ioctl)(adp, cmd, arg));
+ return (0);
case FBIOGETCMAP: /* get color palette */
if (get_palette(adp, ((struct fbcmap *)arg)->index,
@@ -1554,8 +1730,8 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
((struct fbcmap *)arg)->red,
((struct fbcmap *)arg)->green,
((struct fbcmap *)arg)->blue, NULL))
- return (*prevvidsw->ioctl)(adp, cmd, arg);
- return 0;
+ return ((*prevvidsw->ioctl)(adp, cmd, arg));
+ return (0);
case FBIOPUTCMAP: /* set color palette */
if (set_palette(adp, ((struct fbcmap *)arg)->index,
@@ -1563,11 +1739,11 @@ vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
((struct fbcmap *)arg)->red,
((struct fbcmap *)arg)->green,
((struct fbcmap *)arg)->blue, NULL))
- return (*prevvidsw->ioctl)(adp, cmd, arg);
- return 0;
+ return ((*prevvidsw->ioctl)(adp, cmd, arg));
+ return (0);
default:
- return (*prevvidsw->ioctl)(adp, cmd, arg);
+ return ((*prevvidsw->ioctl)(adp, cmd, arg));
}
}
@@ -1579,15 +1755,15 @@ vesa_diag(video_adapter_t *adp, int level)
/* call the previous handler first */
error = (*prevvidsw->diag)(adp, level);
if (error)
- return error;
+ return (error);
if (adp != vesa_adp)
- return 1;
+ return (1);
if (level <= 0)
- return 0;
+ return (0);
- return 0;
+ return (0);
}
static int
@@ -1597,15 +1773,16 @@ vesa_bios_info(int level)
struct vesa_mode vmode;
int i;
#endif
+ uint16_t vers;
+
+ vers = vesa_adp_info->v_version;
if (bootverbose) {
/* general adapter information */
printf(
"VESA: v%d.%d, %dk memory, flags:0x%x, mode table:%p (%x)\n",
- ((vesa_adp_info->v_version & 0xf000) >> 12) * 10 +
- ((vesa_adp_info->v_version & 0x0f00) >> 8),
- ((vesa_adp_info->v_version & 0x00f0) >> 4) * 10 +
- (vesa_adp_info->v_version & 0x000f),
+ (vers >> 12) * 10 + ((vers & 0x0f00) >> 8),
+ ((vers & 0x00f0) >> 4) * 10 + (vers & 0x000f),
vesa_adp_info->v_memsize * 64, vesa_adp_info->v_flags,
vesa_vmodetab, vesa_adp_info->v_modetable);
@@ -1615,9 +1792,9 @@ vesa_bios_info(int level)
}
if (level <= 0)
- return 0;
+ return (0);
- if (vesa_adp_info->v_version >= 0x0200 && bootverbose) {
+ if (vers >= 0x0200 && bootverbose) {
/* vender name, product name, product revision */
printf("VESA: %s %s %s\n",
(vesa_venderstr != NULL) ? vesa_venderstr : "unknown",
@@ -1664,7 +1841,7 @@ vesa_bios_info(int level)
}
#endif /* VESA_DEBUG > 1 */
- return 0;
+ return (0);
}
/* module loading */
@@ -1676,7 +1853,7 @@ vesa_load(void)
int s;
if (vesa_init_done)
- return 0;
+ return (0);
/* locate a VGA adapter */
s = spltty();
@@ -1687,7 +1864,7 @@ vesa_load(void)
if (error == 0)
vesa_bios_info(bootverbose);
- return error;
+ return (error);
}
static int
@@ -1700,7 +1877,7 @@ vesa_unload(void)
/* if the adapter is currently in a VESA mode, don't unload */
if ((vesa_adp != NULL) && VESA_MODE(vesa_adp->va_mode))
- return EBUSY;
+ return (EBUSY);
/*
* FIXME: if there is at least one vty which is in a VESA mode,
* we shouldn't be unloading! XXX
@@ -1725,21 +1902,30 @@ vesa_unload(void)
}
splx(s);
- return error;
+ if (vesa_oemstr != NULL)
+ free(vesa_oemstr, M_DEVBUF);
+ if (vesa_venderstr != NULL)
+ free(vesa_venderstr, M_DEVBUF);
+ if (vesa_prodstr != NULL)
+ free(vesa_prodstr, M_DEVBUF);
+ if (vesa_revstr != NULL)
+ free(vesa_revstr, M_DEVBUF);
+ if (vesa_vmode != &vesa_vmode_empty)
+ free(vesa_vmode, M_DEVBUF);
+ return (error);
}
static int
vesa_mod_event(module_t mod, int type, void *data)
{
+
switch (type) {
case MOD_LOAD:
- return vesa_load();
+ return (vesa_load());
case MOD_UNLOAD:
- return vesa_unload();
- default:
- return EOPNOTSUPP;
+ return (vesa_unload());
}
- return 0;
+ return (EOPNOTSUPP);
}
static moduledata_t vesa_mod = {