- delete sc->sc_screens[]

- BUGFIX: hpcfb_alloc_screen clears real frame buffer
 - Doesn't allocate any screen in attach routine
This commit is contained in:
takemura 2001-07-21 14:49:58 +00:00
parent 6780bcba0b
commit 0f960df346
1 changed files with 67 additions and 87 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: hpcfb.c,v 1.9 2001/07/17 01:37:44 toshii Exp $ */
/* $NetBSD: hpcfb.c,v 1.10 2001/07/21 14:49:58 takemura Exp $ */
/*-
* Copyright (c) 1999
@ -46,7 +46,7 @@
static const char _copyright[] __attribute__ ((unused)) =
"Copyright (c) 1999 Shin Takemura. All rights reserved.";
static const char _rcsid[] __attribute__ ((unused)) =
"$NetBSD: hpcfb.c,v 1.9 2001/07/17 01:37:44 toshii Exp $";
"$NetBSD: hpcfb.c,v 1.10 2001/07/21 14:49:58 takemura Exp $";
#include <sys/param.h>
#include <sys/systm.h>
@ -141,7 +141,6 @@ struct hpcfb_devconfig {
#define HPCFB_DC_SCRTHREAD 0x20 /* in scroll thread or callout */
#define HPCFB_DC_UPDATEALL 0x40 /* need to redraw all */
#define HPCFB_DC_ABORT 0x80 /* abort redrawing */
int dc_scrno;
int dc_memsize;
u_char *dc_fbaddr;
};
@ -152,10 +151,8 @@ struct hpcfb_devconfig {
struct hpcfb_softc {
struct device sc_dev;
struct hpcfb_devconfig *sc_dc; /* device configuration */
struct hpcfb_devconfig *screens[HPCFB_MAX_SCREEN];
const struct hpcfb_accessops *sc_accessops;
void *sc_accessctx;
int nscreens;
void *sc_powerhook; /* power management hook */
struct device *sc_wsdisplay;
int sc_screen_resumed;
@ -167,6 +164,8 @@ struct hpcfb_softc {
void (*sc_switchcb)(void *, int, int);
void *sc_switchcbarg;
struct callout sc_switch_callout;
int sc_nfbconf;
struct hpcfb_fbconf *sc_fbconflist;
};
/*
@ -304,50 +303,26 @@ hpcfbattach(struct device *parent, struct device *self, void *aux)
sc->sc_accessops = ha->ha_accessops;
sc->sc_accessctx = ha->ha_accessctx;
sc->sc_nfbconf = ha->ha_nfbconf;
sc->sc_fbconflist = ha->ha_fbconflist;
if (hpcfbconsole) {
sc->screens[0] =
sc->sc_dc = &hpcfb_console_dc;
sc->nscreens = 1;
sc->sc_dc = &hpcfb_console_dc;
hpcfb_console_dc.dc_sc = sc;
} else {
sc->screens[0] =
sc->sc_dc = (struct hpcfb_devconfig *)
malloc(sizeof(struct hpcfb_devconfig), M_DEVBUF, M_WAITOK);
sc->nscreens = 0; /* XXXX */
memset(sc->sc_dc, 0, sizeof(struct hpcfb_devconfig));
if (hpcfb_init(&ha->ha_fbconflist[0], sc->sc_dc) != 0) {
return;
}
sc->sc_dc->dc_tvram = hpcfb_console_tvram;
memset(hpcfb_console_tvram, 0, sizeof(hpcfb_console_tvram));
sc->sc_dc->dc_sc = sc;
printf(": %dx%d pixels, %d colors, %dx%d chars",
sc->sc_dc->dc_rinfo.ri_width,sc->sc_dc->dc_rinfo.ri_height,
pow(2, sc->sc_dc->dc_rinfo.ri_depth),
sc->sc_dc->dc_rinfo.ri_cols,sc->sc_dc->dc_rinfo.ri_rows);
/* Set video chip dependent CLUT if any. */
if (sc->sc_accessops->setclut)
sc->sc_accessops->setclut(sc->sc_accessctx,
&hpcfb_console_dc.dc_rinfo);
}
printf("\n");
sc->sc_polling = 0; /* XXX */
sc->sc_mapping = 0; /* XXX */
callout_init(&sc->sc_switch_callout);
hpcfb_stdscreen.nrows = sc->sc_dc->dc_rows;
hpcfb_stdscreen.ncols = sc->sc_dc->dc_cols;
hpcfb_stdscreen.capabilities = sc->sc_dc->dc_rinfo.ri_caps;
printf(": hpcrasops %dx%d pixels, %d colors, %dx%d chars: multi",
sc->sc_dc->dc_rinfo.ri_width,
sc->sc_dc->dc_rinfo.ri_height,
pow(2, sc->sc_dc->dc_rinfo.ri_depth),
sc->sc_dc->dc_rinfo.ri_cols,
sc->sc_dc->dc_rinfo.ri_rows);
printf("\n");
/* Set video chip dependent CLUT if any. */
if (hpcfbconsole && sc->sc_accessops->setclut) {
sc->sc_accessops->setclut(sc->sc_accessctx,
&hpcfb_console_dc.dc_rinfo);
}
/* set font for hardware accel */
if (sc->sc_accessops->font) {
sc->sc_accessops->font(sc->sc_accessctx,
sc->sc_dc->dc_rinfo.ri_font);
}
/* Add a power hook to power management */
sc->sc_powerhook = powerhook_establish(hpcfb_power, sc);
@ -424,6 +399,7 @@ hpcfb_cnattach(struct hpcfb_fbconf *fbconf)
struct hpcfb_fbconf __fbconf __attribute__((__unused__));
long defattr;
DPRINTF(("%s(%d): hpcfb_cnattach()\n", __FILE__, __LINE__));
#if NBIVIDEO > 0
if (fbconf == 0) {
memset(&__fbconf, 0, sizeof(struct hpcfb_fbconf));
@ -435,9 +411,12 @@ hpcfb_cnattach(struct hpcfb_fbconf *fbconf)
memset(&hpcfb_console_dc, 0, sizeof(struct hpcfb_devconfig));
if (hpcfb_init(fbconf, &hpcfb_console_dc) != 0)
return (ENXIO);
hpcfb_console_dc.dc_state |= HPCFB_DC_CURRENT;
hpcfb_console_dc.dc_tvram = hpcfb_console_tvram;
/* clear screen */
memset(hpcfb_console_tvram, 0, sizeof(hpcfb_console_tvram));
hpcfb_redraw(&hpcfb_console_dc, 0, hpcfb_console_dc.dc_rows, 1);
hpcfb_console_wsscreen = hpcfb_stdscreen;
hpcfb_console_wsscreen.nrows = hpcfb_console_dc.dc_rows;
@ -491,7 +470,6 @@ hpcfb_init(struct hpcfb_fbconf *fbconf, struct hpcfb_devconfig *dc)
dc->dc_cury = -1;
dc->dc_rows = dc->dc_rinfo.ri_rows;
dc->dc_cols = dc->dc_rinfo.ri_cols;
dc->dc_state |= HPCFB_DC_CURRENT;
#ifdef HPCFB_JUMP
dc->dc_max_row = 0;
dc->dc_min_row = dc->dc_rows;
@ -499,7 +477,6 @@ hpcfb_init(struct hpcfb_fbconf *fbconf, struct hpcfb_devconfig *dc)
callout_init(&dc->dc_scroll_ch);
#endif /* HPCFB_JUMP */
dc->dc_memsize = ri->ri_stride * ri->ri_height;
dc->dc_scrno = 0;
/* hook rasops in hpcfb_ops */
rasops_emul = ri->ri_ops; /* struct copy */
ri->ri_ops = hpcfb_emulops; /* struct copy */
@ -513,7 +490,6 @@ hpcfb_cmap_reorder(struct hpcfb_fbconf *fbconf, struct hpcfb_devconfig *dc)
struct rasops_info *ri = &dc->dc_rinfo;
int reverse = fbconf->hf_access_flags & HPCFB_ACCESS_REVERSE;
int *cmap = ri->ri_devcmap;
vaddr_t fbaddr = (vaddr_t)fbconf->hf_baseaddr;
int i, j, bg, fg, tmp;
/*
@ -552,14 +528,6 @@ hpcfb_cmap_reorder(struct hpcfb_fbconf *fbconf, struct hpcfb_devconfig *dc)
}
break;
}
/* clear the screen */
bg = cmap[0];
for (i = 0;
i < fbconf->hf_height * fbconf->hf_bytes_per_line;
i += sizeof(u_int32_t)) {
*(u_int32_t *)(fbaddr + i) = bg;
}
}
int
@ -569,6 +537,7 @@ hpcfb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
struct hpcfb_devconfig *dc = sc->sc_dc;
struct wsdisplay_fbinfo *wdf;
DPRINTF(("hpcfb_ioctl(cmd=0x%lx)\n", cmd));
switch (cmd) {
case WSKBDIO_BELL:
return (0);
@ -682,6 +651,7 @@ hpcfb_refresh_screen(struct hpcfb_softc *sc)
struct hpcfb_devconfig *dc = sc->sc_dc;
int x, y;
DPRINTF(("hpcfb_refres_screen()\n"));
if (dc == NULL)
return;
@ -715,67 +685,73 @@ hpcfb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
DPRINTF(("%s(%d): hpcfb_alloc_screen()\n", __FILE__, __LINE__));
if (!hpcfbconsole && sc->nscreens > 0) /* XXXXX */
dc = malloc(sizeof(struct hpcfb_devconfig), M_DEVBUF, M_WAITOK);
if (dc == NULL)
return (ENOMEM);
if (sc->nscreens > HPCFB_MAX_SCREEN)
return (ENOMEM);
if (sc->screens[sc->nscreens] == NULL){
sc->screens[sc->nscreens] =
malloc(sizeof(struct hpcfb_devconfig), M_DEVBUF, M_WAITOK);
if (sc->screens[sc->nscreens] == NULL)
return (ENOMEM);
memset(sc->screens[sc->nscreens], 0,
sizeof(struct hpcfb_devconfig));
}
dc = sc->screens[sc->nscreens];
memset(dc, 0, sizeof(struct hpcfb_devconfig));
dc->dc_sc = sc;
/* copy master raster info */
dc->dc_rinfo = sc->sc_dc->dc_rinfo;
if (hpcfb_init(&sc->sc_fbconflist[0], dc) != 0)
return (EINVAL);
if (sc->sc_accessops->font) {
sc->sc_accessops->font(sc->sc_accessctx,
sc->sc_dc->dc_rinfo.ri_font);
}
dc->dc_rinfo.ri_font);
}
/* Set video chip dependent CLUT if any. */
if (sc->sc_accessops->setclut)
sc->sc_accessops->setclut(sc->sc_accessctx, &dc->dc_rinfo);
printf("hpcfb: %dx%d pixels, %d colors, %dx%d chars\n",
dc->dc_rinfo.ri_width, dc->dc_rinfo.ri_height,
pow(2, dc->dc_rinfo.ri_depth),
dc->dc_rinfo.ri_cols, dc->dc_rinfo.ri_rows);
/*
* XXX, wsdisplay won't reffer the information in wsscreen_descr
* structure until alloc_screen will be called, at least, under
* current implementation...
*/
hpcfb_stdscreen.nrows = dc->dc_rows;
hpcfb_stdscreen.ncols = dc->dc_cols;
hpcfb_stdscreen.capabilities = dc->dc_rinfo.ri_caps;
dc->dc_fbaddr = dc->dc_rinfo.ri_bits;
dc->dc_rows = dc->dc_rinfo.ri_rows;
dc->dc_cols = dc->dc_rinfo.ri_cols;
dc->dc_memsize = dc->dc_rinfo.ri_stride * dc->dc_rinfo.ri_height;
dc->dc_scrno = sc->nscreens;
dc->dc_curx = -1;
dc->dc_cury = -1;
dc->dc_tvram = malloc(sizeof(struct hpcfb_tvrow)*dc->dc_rows,
M_DEVBUF, M_WAITOK);
if (dc->dc_tvram == NULL){
dc->dc_tvram =
malloc(sizeof(struct hpcfb_tvrow)*dc->dc_rows,
M_DEVBUF, M_WAITOK);
if (dc->dc_tvram == NULL){
free(sc->screens[sc->nscreens], M_DEVBUF);
sc->screens[sc->nscreens] = NULL;
return (ENOMEM);
}
memset(dc->dc_tvram, 0,
sizeof(struct hpcfb_tvrow)*dc->dc_rows);
free(dc, M_DEVBUF);
return (ENOMEM);
}
memset(dc->dc_tvram, 0, sizeof(struct hpcfb_tvrow)*dc->dc_rows);
*curxp = 0;
*curyp = 0;
sc->nscreens++;
*cookiep = dc;
hpcfb_alloc_attr(*cookiep, 7, 0, 0, attrp);
DPRINTF(("%s(%d): hpcfb_alloc_screen(): 0x%p\n",
__FILE__, __LINE__, dc));
return (0);
}
static void
hpcfb_free_screen(void *v, void *cookie)
{
struct hpcfb_softc *sc = v;
struct hpcfb_devconfig *dc = cookie;
if (sc->nscreens == 1 && sc->sc_dc == &hpcfb_console_dc)
DPRINTF(("%s(%d): hpcfb_free_screen(0x%p)\n",
__FILE__, __LINE__, cookie));
#ifdef DIAGNOSTIC
if (dc == &hpcfb_console_dc)
panic("hpcfb_free_screen: console");
sc->nscreens--;
#endif
free(dc->dc_tvram, M_DEVBUF);
free(dc, M_DEVBUF);
}
static int
@ -786,7 +762,8 @@ hpcfb_show_screen(void *v, void *cookie, int waitok,
struct hpcfb_devconfig *dc = (struct hpcfb_devconfig *)cookie;
struct hpcfb_devconfig *odc;
DPRINTF(("%s(%d): hpcfb_show_screen()\n", __FILE__, __LINE__));
DPRINTF(("%s(%d): hpcfb_show_screen(0x%p)\n",
__FILE__, __LINE__, dc));
odc = sc->sc_dc;
@ -814,6 +791,7 @@ hpcfb_doswitch(struct hpcfb_softc *sc)
struct hpcfb_devconfig *dc;
struct hpcfb_devconfig *odc;
DPRINTF(("hpcfb_doswitch()\n"));
odc = sc->sc_dc;
dc = sc->sc_wantedscreen;
@ -835,7 +813,9 @@ hpcfb_doswitch(struct hpcfb_softc *sc)
/* disable cursor */
/* disable old screen */
odc->dc_state &= ~HPCFB_DC_CURRENT;
/* XXX, This is too dangerous.
odc->dc_rinfo.ri_bits = NULL;
*/
}
/* switch screen to new one */
dc->dc_state |= HPCFB_DC_CURRENT;