summaryrefslogtreecommitdiffstats
path: root/sys/dev/fb/vesa.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/fb/vesa.c')
-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 8a61368..11b9598 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 = {
OpenPOWER on IntegriCloud