Subject: Better semantics for attaching /dev/fb
To: None <port-sparc@NetBSD.ORG>
From: Jason Thorpe <thorpej@SJ.Xenotropic.COM>
List: port-sparc
Date: 11/17/1995 11:24:54
After exchanging an e-mail or two with David Jones, I decided I'd peer
into why his cgtwo was losing while I wait for the world to rebuild. It
appears there's a case where the framebuffer won't get attached, but then
RASTERCONSOLE will try to print to it. This might be the cause of the
data fault David saw.
I fixed a couple of potential buglets in cgtwo.c and removed some
sun4c-specific cruft not really applicable to that driver. Also fixed a
bogus prototype for fb_attach() (it was misnamed fbattach() in the header
file...)
While I was there, I decided to muck about with fixing the framebuffer
attachment semantics. The way things are now, you could really lose if
you have multiple framebuffers on a Sun 4. So, I thought about this and
came up with the following set of diffs (including the cgtwo fixes...)
Basically, what they do is (in this order):
* Check if a framebuffer has been forcefully attached to /dev/fb.
If so, return.
* If we're being forced into /dev/fb (see below), replace any
existing framebuffer, lock out all others, and return.
* If we're the console, replace any existing framebuffer,
only allow forceful replacements, and return.
* Attach the framebuffer, replacing any existing one, and return.
Note that every time a framebuffer is replaced, a message is displayed to
that fact.
With these changes, one may hard-code a /dev/fb by using "flags 0x01" on
the config line in your kernel config file, like this:
bwtwo0 at obio0 addr 0xfd000000 level 4 flags 0x01
David, I can build you a GENERIC kernel for you to try these out, if need be.
I haven't finsihed compiling these changes yet, so there might be a typo
or two, but I figured I'd get them out there anyhow.
Ciao.
------------------------------------------------------------------------------
Jason R. Thorpe thorpej@Xenotropic.COM
Just me and my collection of obsolete computer gear(s).
-----cut here-----
Index: dev/bwtwo.c
===================================================================
RCS file: /usr/og/devsrc/netbsd/src/sys/arch/sparc/dev/bwtwo.c,v
retrieving revision 1.10
diff -c -r1.10 bwtwo.c
*** bwtwo.c 1995/11/17 10:35:03 1.10
--- bwtwo.c 1995/11/17 18:59:56
***************
*** 153,158 ****
--- 153,159 ----
sc->sc_fb.fb_driver = &bwtwofbdriver;
sc->sc_fb.fb_device = &sc->sc_dev;
sc->sc_fb.fb_type.fb_type = FBTYPE_SUN2BW;
+ sc->sc_fb.fb_flags = sc->sc_dev->dv_cfdata->cf_flags;
switch (ca->ca_bustype) {
case BUS_OBIO:
***************
*** 232,243 ****
if (sbus)
sbus_establish(&sc->sc_sd, &sc->sc_dev);
#endif
- /*
- * XXX: this could cause a panic in fb_attach() if more
- * than one frame buffer device is found on a Sun 4.
- */
if (node == fbnode || cputyp == CPU_SUN4)
! fb_attach(&sc->sc_fb);
}
int
--- 233,240 ----
if (sbus)
sbus_establish(&sc->sc_sd, &sc->sc_dev);
#endif
if (node == fbnode || cputyp == CPU_SUN4)
! fb_attach(&sc->sc_fb, isconsole);
}
int
Index: dev/cgsix.c
===================================================================
RCS file: /usr/og/devsrc/netbsd/src/sys/arch/sparc/dev/cgsix.c,v
retrieving revision 1.1.1.4
diff -c -r1.1.1.4 cgsix.c
*** cgsix.c 1995/10/08 13:31:00 1.1.1.4
--- cgsix.c 1995/11/17 19:00:09
***************
*** 184,189 ****
--- 184,190 ----
sc->sc_fb.fb_driver = &cg6_fbdriver;
sc->sc_fb.fb_device = &sc->sc_dev;
sc->sc_fb.fb_type.fb_type = FBTYPE_SUNFAST_COLOR;
+ sc->sc_fb.fb_flags = sc->sc_dev->dv_cfdata->cf_flags;
switch (ca->ca_bustype) {
case BUS_OBIO:
***************
*** 254,260 ****
if (sbus)
sbus_establish(&sc->sc_sd, &sc->sc_dev);
if (node == fbnode)
! fb_attach(&sc->sc_fb);
}
int
--- 255,261 ----
if (sbus)
sbus_establish(&sc->sc_sd, &sc->sc_dev);
if (node == fbnode)
! fb_attach(&sc->sc_fb, isconsole);
}
int
Index: dev/cgthree.c
===================================================================
RCS file: /usr/og/devsrc/netbsd/src/sys/arch/sparc/dev/cgthree.c,v
retrieving revision 1.1.1.4
diff -c -r1.1.1.4 cgthree.c
*** cgthree.c 1995/10/08 13:31:04 1.1.1.4
--- cgthree.c 1995/11/17 19:00:26
***************
*** 149,154 ****
--- 149,155 ----
sc->sc_fb.fb_driver = &cgthreefbdriver;
sc->sc_fb.fb_device = &sc->sc_dev;
+ sc->sc_fb.fb_flags = sc->sc_dev->dv_cfdata->cf_flags;
/*
* The defaults below match my screen, but are not guaranteed
* to be correct as defaults go...
***************
*** 215,221 ****
if (sbus)
sbus_establish(&sc->sc_sd, &sc->sc_dev);
if (node == fbnode)
! fb_attach(&sc->sc_fb);
}
int
--- 216,222 ----
if (sbus)
sbus_establish(&sc->sc_sd, &sc->sc_dev);
if (node == fbnode)
! fb_attach(&sc->sc_fb, isconsole);
}
int
Index: dev/cgtwo.c
===================================================================
RCS file: /usr/og/devsrc/netbsd/src/sys/arch/sparc/dev/cgtwo.c,v
retrieving revision 1.1.1.5
diff -c -r1.1.1.5 cgtwo.c
*** cgtwo.c 1995/11/17 05:01:45 1.1.1.5
--- cgtwo.c 1995/11/17 19:02:21
***************
*** 71,82 ****
#endif
#include <machine/cgtworeg.h>
- #include <sparc/dev/sbusvar.h>
/* per-display variables */
struct cgtwo_softc {
struct device sc_dev; /* base device */
- struct sbusdev sc_sd; /* sbus device */
struct fbdevice sc_fb; /* frame buffer device */
caddr_t sc_phys; /* display RAM (phys addr) */
volatile struct cg2statusreg *sc_reg; /* CG2 control registers */
--- 71,80 ----
***************
*** 158,173 ****
register int node, i;
register struct cgtwo_all *p;
int isconsole;
- int sbus = 1;
char *nam;
sc->sc_fb.fb_driver = &cgtwofbdriver;
sc->sc_fb.fb_device = &sc->sc_dev;
sc->sc_fb.fb_type.fb_type = FBTYPE_SUN2COLOR;
switch (ca->ca_bustype) {
case BUS_VME16:
! sbus = node = 0;
nam = "cgtwo";
break;
--- 156,171 ----
register int node, i;
register struct cgtwo_all *p;
int isconsole;
char *nam;
sc->sc_fb.fb_driver = &cgtwofbdriver;
sc->sc_fb.fb_device = &sc->sc_dev;
sc->sc_fb.fb_type.fb_type = FBTYPE_SUN2COLOR;
+ sc->sc_fb.fb_flags = sc->sc_dev->dv_cfdata->cf_flags;
switch (ca->ca_bustype) {
case BUS_VME16:
! node = 0;
nam = "cgtwo";
break;
***************
*** 204,213 ****
isconsole = 0;
}
#endif
- #if defined(SUN4C) || defined(SUN4M)
- if (cputyp == CPU_SUN4C || cputyp == CPU_SUN4M)
- isconsole = node == fbnode && fbconstty != NULL;
- #endif
sc->sc_phys = (caddr_t)ca->ca_ra.ra_paddr;
if ((sc->sc_fb.fb_pixels = ca->ca_ra.ra_vaddr) == NULL && isconsole) {
/* this probably cannot happen, but what the heck */
--- 202,207 ----
***************
*** 236,245 ****
#endif
} else
printf("\n");
! if (sbus)
! sbus_establish(&sc->sc_sd, &sc->sc_dev);
! if (node == fbnode)
! fb_attach(&sc->sc_fb);
}
int
--- 230,237 ----
#endif
} else
printf("\n");
! if (node == fbnode || cputyp == CPU_SUN4)
! fb_attach(&sc->sc_fb, isconsole);
}
int
Index: dev/fb.c
===================================================================
RCS file: /usr/og/devsrc/netbsd/src/sys/arch/sparc/dev/fb.c,v
retrieving revision 1.3
diff -c -r1.3 fb.c
*** fb.c 1995/10/08 18:28:17 1.3
--- fb.c 1995/11/17 18:50:27
***************
*** 72,83 ****
}
void
! fb_attach(fb)
struct fbdevice *fb;
{
! if (devfb) panic("multiple /dev/fb declarers");
devfb = fb;
}
int
--- 72,142 ----
}
void
! fb_attach(fb, isconsole)
struct fbdevice *fb;
+ int isconsole;
{
+ static int no_replace, seen_force;
! /*
! * We've already had a framebuffer forced into /dev/fb. Don't
! * allow any more, even if this is the console.
! */
! if (seen_force) {
! if (devfb) { /* sanity */
! printf("%s: /dev/fb already full\n",
! fb->fb_device->dv_xname);
! return;
! } else
! seen_force = 0;
! }
!
! /*
! * Check to see if we're being forced into /dev/fb.
! */
! if (fb->fb_flags & FB_FORCE) {
! if (devfb)
! printf("%s: forcefully replaced %s\n",
! fb->fb_device->dv_xname,
! devfb->fb_device->dv_xname);
! devfb = fb;
! seen_force = no_replace = 1;
! goto attached;
! }
!
! /*
! * Check to see if we're the console. If we are, then replace
! * any currently existing framebuffer.
! */
! if (isconsole) {
! if (devfb)
! printf("%s: replaced %s\n", fb->fb_device->dv_xname,
! devfb->fb_device->dv_xname);
! devfb = fb;
! no_replace = 1;
! goto attached;
! }
!
! /*
! * For the final case, we check to see if we can replace an
! * existing framebuffer, if not, say so and return.
! */
! if (no_replace) {
! if (devfb) { /* sanity */
! printf("%s: /dev/fb already full\n",
! fb->fb_device->dv_xname);
! return;
! } else
! no_replace = 0;
! }
!
! if (devfb)
! printf("%s: replaced %d\n", fb->fb_device->dv_xname,
! devfb->fb_device->dv_xname);
devfb = fb;
+
+ attached:
+ printf("%s: attached to /dev/fb\n", devfb->fb_device->dv_xname);
}
int
Index: include/fbvar.h
===================================================================
RCS file: /usr/og/devsrc/netbsd/src/sys/arch/sparc/include/fbvar.h,v
retrieving revision 1.1.1.4
diff -c -r1.1.1.4 fbvar.h
*** fbvar.h 1995/10/08 13:32:20 1.1.1.4
--- fbvar.h 1995/11/17 18:55:48
***************
*** 76,88 ****
struct fbdriver *fb_driver; /* pointer to driver */
struct device *fb_device; /* parameter for fbd_unblank */
#ifdef RASTERCONSOLE
/* Raster console emulator state */
struct rconsole fb_rcons;
#endif
};
! void fbattach __P((struct fbdevice *));
void fb_setsize __P((struct fbdevice *, int, int, int, int, int));
#ifdef RASTERCONSOLE
void fbrcons_init __P((struct fbdevice *));
--- 76,91 ----
struct fbdriver *fb_driver; /* pointer to driver */
struct device *fb_device; /* parameter for fbd_unblank */
+ int fb_flags; /* flags from config */
+ #define FB_FORCE 0x00000001 /* force device into /dev/fb */
+
#ifdef RASTERCONSOLE
/* Raster console emulator state */
struct rconsole fb_rcons;
#endif
};
! void fb_attach __P((struct fbdevice *, int));
void fb_setsize __P((struct fbdevice *, int, int, int, int, int));
#ifdef RASTERCONSOLE
void fbrcons_init __P((struct fbdevice *));