xref: /csrg-svn/sys/news3400/iop/fb.c (revision 63308)
153887Smckusick /*
2*63308Sbostic  * Copyright (c) 1992, 1993
3*63308Sbostic  *	The Regents of the University of California.  All rights reserved.
453887Smckusick  *
553887Smckusick  * This code is derived from software contributed to Berkeley by
653887Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753887Smckusick  *
853887Smckusick  * %sccs.include.redist.c%
953887Smckusick  *
1053887Smckusick  * from: $Hdr: fb.c,v 4.300 91/06/27 20:43:06 root Rel41 $ SONY
1153887Smckusick  *
12*63308Sbostic  *	@(#)fb.c	8.1 (Berkeley) 06/11/93
1353887Smckusick  */
1453887Smckusick 
1553887Smckusick #include "fb.h"
1653887Smckusick #if NFB > 0
1753887Smckusick /*
1853887Smckusick  * Frame buffer driver
1953887Smckusick  */
2053887Smckusick 
2157183Sutashiro #include <sys/types.h>
2257183Sutashiro #include <machine/pte.h>
2357183Sutashiro #include <machine/cpu.h>
2453887Smckusick 
2557183Sutashiro #include <sys/param.h>
2657183Sutashiro #include <sys/proc.h>
2757183Sutashiro #include <sys/user.h>
2857183Sutashiro #include <sys/buf.h>
2957183Sutashiro #include <vm/vm.h>
3057183Sutashiro #include <sys/systm.h>
3157183Sutashiro #include <sys/map.h>
3257183Sutashiro #include <sys/uio.h>
3357183Sutashiro #include <sys/kernel.h>
3453887Smckusick 
3557183Sutashiro #include <news3400/iop/framebuf.h>
3657183Sutashiro #include <news3400/iop/fbreg.h>
3757183Sutashiro #include <news3400/iodev/ioptohb.h>
3853887Smckusick 
3953887Smckusick #ifdef CPU_SINGLE
4057183Sutashiro #include <news3400/hbdev/hbvar.h>
4153887Smckusick 
4253887Smckusick #define ipc_phys(x)	(caddr_t)((int)(x))
4353887Smckusick #define ipc_log(x)	(caddr_t)((int)(x) | 0x80000000)
4453887Smckusick 
4553887Smckusick #define iop_driver	hb_driver
4653887Smckusick #define iop_device	hb_device
4753887Smckusick 
4853887Smckusick extern rop_xint();
4953887Smckusick #else /* CPU_SINGLE */
5057183Sutashiro #include <news3400/iop/iopvar.h>
5153887Smckusick 
5253887Smckusick #ifdef IPC_MRX
5353887Smckusick #include "../ipc/newsipc.h"
5453887Smckusick 
5553887Smckusick #ifdef mips
5653887Smckusick #define ipc_phys(x)	K0_TT0(x)
5753887Smckusick #define ipc_log(x)	TT0_K0(x)
5853887Smckusick #else
5953887Smckusick #define	ipc_phys(x)	(caddr_t)((int)(x) & ~0x80000000)
6053887Smckusick #define	ipc_log(x)	(caddr_t)((int)(x) | 0x80000000)
6153887Smckusick #endif
6253887Smckusick 
6353887Smckusick static int port_fb, port_fb_iop;
6453887Smckusick #endif /* IPC_MRX */
6553887Smckusick #endif /* CPU_SINGLE */
6653887Smckusick 
6753887Smckusick #define FB_USED		1
6853887Smckusick #define VIDEO_USED	2
6953887Smckusick 
7053887Smckusick /*
7153887Smckusick  * driver definition
7253887Smckusick  */
7353887Smckusick int fbprobe(), fbattach();
7453887Smckusick 
7553887Smckusick struct iop_device *fbinfo[NFB];
7653887Smckusick struct iop_driver fbdriver =
7753887Smckusick #ifdef CPU_SINGLE
7853887Smckusick 	{ fbprobe, 0, fbattach, 0, 0, "fb", fbinfo, "fbc", 0, 0 };
7953887Smckusick #else
8053887Smckusick 	{ fbprobe, 0, fbattach, 0, "fb", fbinfo };
8153887Smckusick #endif
8253887Smckusick 
8353887Smckusick /* static */
8453887Smckusick static struct fb_softc fb_softc[NFB];
8553887Smckusick static struct fbreg	fbreg[NFB];
8653887Smckusick static int fbstate;
8753887Smckusick static struct fbreg	*last_fb;
8853887Smckusick 
8953887Smckusick static char *devname[] = {
9053887Smckusick /* 0*/	"",
9153887Smckusick /* 1*/	"NWB-512",
9253887Smckusick /* 2*/	"NWB-225",
9353887Smckusick /* 3*/	"POP-MONO",
9453887Smckusick /* 4*/	"POP-COLOR",
9553887Smckusick /* 5*/	"NWB-514",
9653887Smckusick /* 6*/	"NWB-251",
9753887Smckusick /* 7*/	"LCD-MONO",
9853887Smckusick /* 8*/	"LDC-COLOR",
9953887Smckusick /* 9*/	"NWB-518",
10053887Smckusick /*10*/	"NWB-252",
10153887Smckusick /*11*/	"NWB-253",
10253887Smckusick /*12*/	"NWB-254",
10353887Smckusick /*13*/	"NWB-255",
10453887Smckusick /*14*/	"SLB-101",
10553887Smckusick /*15*/	"NWB-256",
10653887Smckusick /*16*/	"NWB-257",
10753887Smckusick };
10853887Smckusick 
10953887Smckusick static void	fblock(), fbunlock(), fbreset();
11053887Smckusick static int	fbinit();
11153887Smckusick 
11253887Smckusick #ifdef CPU_DOUBLE
11353887Smckusick #ifdef USE_RAW_INTR
11453887Smckusick 
11553887Smckusick #include "../mrx/h/ipc.h"
11653887Smckusick 
11753887Smckusick #ifdef mips
11853887Smckusick # define	FB_ADDR		&IPC_ARG(&ipc_block, ARG_CPU, 4)
11953887Smckusick #else
12053887Smckusick # define	FB_ADDR		&IPC_ARG(&ipc_block, ARG_CPU0, 4)
12153887Smckusick # define	volatile
12253887Smckusick #endif
12353887Smckusick 
12453887Smckusick typedef struct fbreg *fbregp;
12553887Smckusick int fb_waiting;
12653887Smckusick 
Xfb_intr(chan,arg)12753887Smckusick Xfb_intr(chan, arg)
12853887Smckusick 	int chan;
12953887Smckusick 	int arg;
13053887Smckusick {
13153887Smckusick 
13253887Smckusick 	intrcnt[INTR_BITMAP]++;
13353887Smckusick 	if (fb_waiting) {
13453887Smckusick 		fb_waiting = 0;
13553887Smckusick 		wakeup((caddr_t)&fb_waiting);
13653887Smckusick 	}
13753887Smckusick }
13853887Smckusick 
13953887Smckusick static void
fbwait()14053887Smckusick fbwait()
14153887Smckusick {
14253887Smckusick 	int s = splfb();
14353887Smckusick 
14453887Smckusick 	while (*(volatile fbregp *)FB_ADDR) {
14553887Smckusick 		fb_waiting = 1;
14653887Smckusick 		sleep((caddr_t)&fb_waiting, FBPRI);
14753887Smckusick 	}
14853887Smckusick 	(void) splx(s);
14953887Smckusick }
15053887Smckusick 
15153887Smckusick void
fbstart(fbp,wait)15253887Smckusick fbstart(fbp, wait)
15353887Smckusick 	struct fbreg *fbp;
15453887Smckusick 	int wait;
15553887Smckusick {
15653887Smckusick 
15753887Smckusick 	fbwait();
15853887Smckusick 	*(volatile fbregp *)FB_ADDR =
15953887Smckusick #ifdef mips
16053887Smckusick 	    (volatile fbregp)ipc_phys(MACH_UNCACHED_TO_CACHED(fbp));
16153887Smckusick #else
16253887Smckusick 	    (volatile fbregp)ipc_phys(fbp);
16353887Smckusick #endif
16453887Smckusick 	if (wait)
16553887Smckusick 		fbwait();
16653887Smckusick }
16753887Smckusick 
16853887Smckusick #else /* USE_RAW_INTR */
16953887Smckusick 
17053887Smckusick void
fbstart(fbp,wait)17153887Smckusick fbstart(fbp, wait)
17253887Smckusick 	register struct fbreg *fbp;
17353887Smckusick 	int wait;
17453887Smckusick {
17553887Smckusick 	int s = splfb();
17653887Smckusick 
17753887Smckusick #ifdef IPC_MRX
17853887Smckusick 	msg_send(port_fb_iop, port_fb, fbp, sizeof(*fbp), MSG_INDIRECT);
17953887Smckusick #endif
18053887Smckusick 
18153887Smckusick 	last_fb = fbp;
18253887Smckusick 	if (wait) {
18353887Smckusick 		fbstate |= FB_WAIT;
18453887Smckusick 		sleep((caddr_t)fbreg, FBPRI);
18553887Smckusick 	} else {
18653887Smckusick 		fbstate |= FB_DELAY;
18753887Smckusick 	}
18853887Smckusick 	splx(s);
18953887Smckusick }
19053887Smckusick 
19153887Smckusick void
fbcint(arg)19253887Smckusick fbcint(arg)
19353887Smckusick 	int arg;
19453887Smckusick {
19553887Smckusick 
19653887Smckusick 	intrcnt[INTR_BITMAP]++;
19753887Smckusick 
19853887Smckusick #ifdef IPC_MRX
19953887Smckusick 	msg_recv(arg, NULL, NULL, NULL, 0);
20053887Smckusick #ifdef mips
20153887Smckusick 	clean_dcache((caddr_t)last_fb, sizeof(struct fbreg));
20253887Smckusick #endif
20353887Smckusick #endif /* IPC_MRX */
20453887Smckusick 
20553887Smckusick 	if (fbstate & FB_WAIT) {
20653887Smckusick 		fbstate &= ~FB_WAIT;
20753887Smckusick 		wakeup((caddr_t)fbreg);
20853887Smckusick 	} else if (fbstate & FB_DELAY) {
20953887Smckusick 		fbstate &= ~FB_DELAY;
21053887Smckusick 	} else if (fbstate & FB_DELAY2) {
21153887Smckusick 		fbstate &= ~(FB_BUSY|FB_DELAY2);
21253887Smckusick 		if (fbstate & FB_WANTED) {
21353887Smckusick 			fbstate &= ~FB_WANTED;
21453887Smckusick 			wakeup((caddr_t)&fbstate);
21553887Smckusick 		}
21653887Smckusick 	}
21753887Smckusick 	return;
21853887Smckusick }
21953887Smckusick #endif /* USE_RAW_INTR */
22053887Smckusick #endif /* CPU_DOUBLE */
22153887Smckusick 
22253887Smckusick /* ARGSUSED */
22353887Smckusick fbprobe(ii)
22453887Smckusick 	struct iop_device *ii;
22553887Smckusick {
22653887Smckusick 	register int unit = ii->ii_unit;
22753887Smckusick 	register struct fb_softc *fb = &fb_softc[unit];
22853887Smckusick #if defined(IPC_MRX) && defined(mips)
22953887Smckusick 	register struct fbreg *fbp =
23053887Smckusick 	    (struct fbreg *)MACH_CACHED_TO_UNCACHED(&fbreg[unit]);
23153887Smckusick #else
23253887Smckusick 	register struct fbreg *fbp = &fbreg[unit];
23353887Smckusick #endif
23453887Smckusick 
23553887Smckusick #ifdef CPU_SINGLE
23653887Smckusick 	if (unit == 0)
23753887Smckusick 		register_hb_intr2(rop_xint, ii->ii_unit, ii->ii_intr);
23853887Smckusick #endif
23953887Smckusick 
24053887Smckusick #ifdef IPC_MRX
24153887Smckusick 	if (port_fb_iop <= 0) {
24253887Smckusick #ifdef USE_RAW_INTR
24353887Smckusick 		register_ipcintr(4, Xfb_intr);
24453887Smckusick #endif
24553887Smckusick 		port_fb_iop = object_query("framebuf");
24653887Smckusick 		if (port_fb_iop <= 0) {
24753887Smckusick 			return (0);
24853887Smckusick 		}
24953887Smckusick #ifndef USE_RAW_INTR
25053887Smckusick 		port_fb = port_create("@port_fb", fbcint, -1);
25153887Smckusick #endif
25253887Smckusick 	}
25353887Smckusick #endif /* IPC_MRX */
25453887Smckusick 
25553887Smckusick 	fbp->fb_command = FB_CPROBE;
25653887Smckusick 	fbp->fb_device = 0;
25753887Smckusick 	fbp->fb_unit = unit;
25853887Smckusick 	fbp->fb_data = -1;
25953887Smckusick 	fbstart(fbp, 1);
26053887Smckusick 
26153887Smckusick 	if ((fb->fbs_device = fbp->fb_data) == -1)
26253887Smckusick 		return (0);
26353887Smckusick 	else
26453887Smckusick 		return (-1);
26553887Smckusick }
26653887Smckusick 
26753887Smckusick /* ARGSUSED */
26853887Smckusick fbattach(ii)
26953887Smckusick 	struct iop_device *ii;
27053887Smckusick {
27153887Smckusick 	register int unit = ii->ii_unit;
27253887Smckusick 	register struct fb_softc *fb = &fb_softc[unit];
27353887Smckusick #if defined(IPC_MRX) && defined(mips)
27453887Smckusick 	register struct fbreg *fbp =
27553887Smckusick 	    (struct fbreg *)MACH_CACHED_TO_UNCACHED(&fbreg[unit]);
27653887Smckusick #else
27753887Smckusick 	register struct fbreg *fbp = &fbreg[unit];
27853887Smckusick #endif
27953887Smckusick 
28053887Smckusick 	fbp->fb_command = FB_CATTACH;
28153887Smckusick 	fbp->fb_device = fb->fbs_device;
28253887Smckusick 	fbstart(fbp, 1);
28353887Smckusick 	fb->fbs_type = fbp->fb_scrtype;
28453887Smckusick 
28553887Smckusick 	if (fb->fbs_type.type) {
28653887Smckusick 		fb->fbs_state = 0;
28753887Smckusick 		fb->fbs_flag = 0;
28853887Smckusick 		printf("fb%d: %s", unit,
28953887Smckusick 			(fb->fbs_type.type < sizeof(devname)/sizeof(*devname))
29053887Smckusick 				? devname[fb->fbs_type.type] : "UNKNOWN");
29153887Smckusick 		printf(" (%d x %d %d plane)\n",
29253887Smckusick 				fb->fbs_type.visiblerect.extent.x,
29353887Smckusick 				fb->fbs_type.visiblerect.extent.y,
29453887Smckusick 				fb->fbs_type.plane);
29553887Smckusick 	}
29653887Smckusick }
29753887Smckusick 
29853887Smckusick /*ARGSUSED*/
fbopen(dev,flag)29953887Smckusick fbopen(dev, flag)
30053887Smckusick 	dev_t dev;
30153887Smckusick 	int flag;
30253887Smckusick {
30353887Smckusick 	register int unit = FBUNIT(dev);
30453887Smckusick 	register struct fb_softc *fb = &fb_softc[unit];
30553887Smckusick 	register struct iop_device *ii;
30653887Smckusick #if defined(IPC_MRX) && defined(mips)
30753887Smckusick 	register struct fbreg *fbp =
30853887Smckusick 	    (struct fbreg *)MACH_CACHED_TO_UNCACHED(&fbreg[unit]);
30953887Smckusick #else
31053887Smckusick 	register struct fbreg *fbp = &fbreg[unit];
31153887Smckusick #endif
31253887Smckusick 
31353887Smckusick 	if (unit >= NFB || (ii = fbinfo[unit]) == 0 || ii->ii_alive == 0)
31453887Smckusick 		return (ENXIO);
31553887Smckusick 	if (fb->fbs_flag && !FBVIDEO(dev))
31653887Smckusick 		return (EBUSY);
31753887Smckusick 
31853887Smckusick 	if (fb->fbs_state == 0) {
31953887Smckusick 		fbp->fb_device = fb->fbs_device;
32053887Smckusick 		if(fbinit(fbp))
32153887Smckusick 			return (EBUSY);
32253887Smckusick 	}
32353887Smckusick 
32453887Smckusick         fb->fbs_state |= FBVIDEO(dev) ? VIDEO_USED : FB_USED;
32553887Smckusick 
32653887Smckusick 	return (0);
32753887Smckusick }
32853887Smckusick 
32953887Smckusick /*ARGSUSED*/
fbclose(dev,flag)33053887Smckusick fbclose(dev, flag)
33153887Smckusick 	dev_t dev;
33253887Smckusick 	int flag;
33353887Smckusick {
33453887Smckusick 	register int unit = FBUNIT(dev);
33553887Smckusick 	register struct fb_softc *fb = &fb_softc[unit];
33653887Smckusick 	register struct iop_device *ii;
33753887Smckusick #if defined(IPC_MRX) && defined(mips)
33853887Smckusick 	register struct fbreg *fbp =
33953887Smckusick 	    (struct fbreg *)MACH_CACHED_TO_UNCACHED(&fbreg[unit]);
34053887Smckusick #else
34153887Smckusick 	register struct fbreg *fbp = &fbreg[unit];
34253887Smckusick #endif
34353887Smckusick 
34453887Smckusick 	if (unit >= NFB || (ii = fbinfo[unit]) == 0 || ii->ii_alive == 0)
34553887Smckusick 		return (ENXIO);
34653887Smckusick 
34753887Smckusick 	if (fb->fbs_state == 0)
34853887Smckusick 		return(0);
34953887Smckusick 
35053887Smckusick 	if(!FBVIDEO(dev))
35153887Smckusick 		fb->fbs_flag = 0;
35253887Smckusick 
35353887Smckusick 	fb->fbs_state &= ~(FBVIDEO(dev) ? VIDEO_USED : FB_USED);
35453887Smckusick 
35553887Smckusick 	if (fb->fbs_state == 0) {
35653887Smckusick 		fbp->fb_device = fb->fbs_device;
35753887Smckusick 		fbreset(fbp);
35853887Smckusick 	}
35953887Smckusick 
36053887Smckusick 	return (0);
36153887Smckusick }
36253887Smckusick 
fbioctl(dev,cmd,data,flag)36353887Smckusick fbioctl(dev, cmd, data, flag)
36453887Smckusick 	dev_t dev;
36553887Smckusick 	caddr_t data;
36653887Smckusick {
36753887Smckusick 	register int unit = FBUNIT(dev);
36853887Smckusick 	register struct fb_softc *fb = &fb_softc[unit];
36953887Smckusick 	register struct iop_device *ii;
37053887Smckusick 	register int error = 0;
37153887Smckusick #if defined(IPC_MRX) && defined(mips)
37253887Smckusick 	register struct fbreg *fbp =
37353887Smckusick 	    (struct fbreg *)MACH_CACHED_TO_UNCACHED(&fbreg[unit]);
37453887Smckusick #else
37553887Smckusick 	register struct fbreg *fbp = &fbreg[unit];
37653887Smckusick #endif
37753887Smckusick 
37853887Smckusick 	if (unit >= NFB || (ii = fbinfo[unit]) == 0 || ii->ii_alive == 0)
37953887Smckusick 		return (ENXIO);
38053887Smckusick 
38153887Smckusick 	fblock();
38253887Smckusick 
38353887Smckusick 	fbp->fb_device = fb->fbs_device;
38453887Smckusick 
38553887Smckusick 	switch (cmd) {
38653887Smckusick 	case FBIOCENABLE:
38753887Smckusick 		fb->fbs_flag = 0;
38853887Smckusick 		break;
38953887Smckusick 	case FBIOCDISABLE:
39053887Smckusick 		fb->fbs_flag = 1;
39153887Smckusick 		break;
39253887Smckusick 	case FBIOCAUTODIM:
39353887Smckusick 		fbp->fb_command = FB_CAUTODIM;
39453887Smckusick 		fbp->fb_data = *((int *)data);
39553887Smckusick 		fbstart(fbp, 0);
39653887Smckusick 		break;
39753887Smckusick 	case FBIOCSETDIM:
39853887Smckusick 		fbp->fb_command = FB_CSETDIM;
39953887Smckusick 		fbp->fb_data = *((int*)data);
40053887Smckusick 		fbstart(fbp, 0);
40153887Smckusick 		break;
40253887Smckusick 	case FBIOCGETDIM:
40353887Smckusick 		fbp->fb_command = FB_CGETDIM;
40453887Smckusick 		fbstart(fbp, 1);
40553887Smckusick 		*((int*)data) = fbp->fb_data;
40653887Smckusick 		break;
40753887Smckusick 	case FBIOCBITBLT:
40853887Smckusick 		error = fbbitblt(fbp, (sBitblt *)data);
40953887Smckusick 		break;
41053887Smckusick 	case FBIOCNBITBLT:
41153887Smckusick 		error = fbnbitblt(fbp, (lBitblt *)data, UIO_USERSPACE);
41253887Smckusick 		break;
41353887Smckusick 	case FBIOCBATCHBITBLT:
41453887Smckusick 		error = fbbatchbitblt(fbp, (sBatchBitblt*)data, UIO_USERSPACE);
41553887Smckusick 		break;
41653887Smckusick 	case FBIOCNBATCHBITBLT:
41753887Smckusick 		error = fbnbatchbitblt(fbp, (lBatchBitblt*)data, UIO_USERSPACE);
41853887Smckusick 		break;
41953887Smckusick 	case FBIOCTILEBITBLT:
42053887Smckusick 		error = fbtilebitblt(fbp, (sTileBitblt *)data);
42153887Smckusick 		break;
42253887Smckusick 	case FBIOCNTILEBITBLT:
42353887Smckusick 		error = fbntilebitblt(fbp, (lTileBitblt *)data);
42453887Smckusick 		break;
42553887Smckusick 	case FBIOCBITBLT3:
42653887Smckusick 		error = fbbitblt3(fbp, (sBitblt3 *)data);
42753887Smckusick 		break;
42853887Smckusick 	case FBIOCNBITBLT3:
42953887Smckusick 		error = fbnbitblt3(fbp, (lBitblt3 *)data);
43053887Smckusick 		break;
43153887Smckusick 	case FBIOCPOLYLINE:
43253887Smckusick 		error = fbpolyline(fbp, (sPrimLine *)data, 0);
43353887Smckusick 		break;
43453887Smckusick 	case FBIOCNPOLYLINE:
43553887Smckusick 		error = fbnpolyline(fbp, (lPrimLine *)data, 0, UIO_USERSPACE);
43653887Smckusick 		break;
43753887Smckusick 	case FBIOCDJPOLYLINE:
43853887Smckusick 		error = fbpolyline(fbp, (sPrimLine *)data, 1);
43953887Smckusick 		break;
44053887Smckusick 	case FBIOCNDJPOLYLINE:
44153887Smckusick 		error = fbnpolyline(fbp, (lPrimLine *)data, 1, UIO_USERSPACE);
44253887Smckusick 		break;
44353887Smckusick 	case FBIOCPOLYMARKER:
44453887Smckusick 		error = fbpolymarker(fbp, (sPrimMarker *)data);
44553887Smckusick 		break;
44653887Smckusick 	case FBIOCNPOLYMARKER:
44753887Smckusick 		error = fbnpolymarker(fbp, (lPrimMarker *)data, UIO_USERSPACE);
44853887Smckusick 		break;
44953887Smckusick 	case FBIOCRECTANGLE:
45053887Smckusick 		error = fbrectangle(fbp, (sPrimRect *)data);
45153887Smckusick 		break;
45253887Smckusick 	case FBIOCNRECTANGLE:
45353887Smckusick 		error = fbnrectangle(fbp, (lPrimRect *)data);
45453887Smckusick 		break;
45553887Smckusick 	case FBIOCFILLSCAN:
45653887Smckusick 		error = fbfillscan(fbp, (sPrimFill *)data);
45753887Smckusick 		break;
45853887Smckusick 	case FBIOCNFILLSCAN:
45953887Smckusick 		error = fbnfillscan(fbp, (lPrimFill *)data, UIO_USERSPACE);
46053887Smckusick 		break;
46153887Smckusick 	case FBIOCTEXT:
46253887Smckusick 		error = fbtext(fbp, (sPrimText *)data);
46353887Smckusick 		break;
46453887Smckusick 	case FBIOCNTEXT:
46553887Smckusick 		error = fbntext(fbp, (lPrimText *)data);
46653887Smckusick 		break;
46753887Smckusick 	case FBIOCPOLYDOT:
46853887Smckusick 		error = fbpolydot(fbp, (sPrimDot *)data);
46953887Smckusick 		break;
47053887Smckusick 	case FBIOCNPOLYDOT:
47153887Smckusick 		error = fbnpolydot(fbp, (lPrimDot *)data, UIO_USERSPACE);
47253887Smckusick 		break;
47353887Smckusick 
47453887Smckusick 	case FBIOCGETSCRTYPE:
47553887Smckusick 		fbgetscrtype(fbp, (sScrType *)data);
47653887Smckusick 		break;
47753887Smckusick 	case FBIOCNGETSCRTYPE:
47853887Smckusick 		fbp->fb_command = FB_CGETSCRTYPE;
47953887Smckusick 		fbstart(fbp, 1);
48053887Smckusick 		*((lScrType*)data) = fbp->fb_scrtype;
48153887Smckusick 		break;
48253887Smckusick 	case FBIOCSETPALETTE:
48353887Smckusick 		fbsetpalette(fbp, (sPalette *)data);
48453887Smckusick 		break;
48553887Smckusick 	case FBIOCNSETPALETTE:
48653887Smckusick 		error = fbnsetpalette(fbp, (lPalette *)data);
48753887Smckusick 		break;
48853887Smckusick 	case FBIOCGETPALETTE:
48953887Smckusick 		fbgetpalette(fbp, (sPalette *)data);
49053887Smckusick 		break;
49153887Smckusick 	case FBIOCNGETPALETTE:
49253887Smckusick 		error = fbngetpalette(fbp, (lPalette *)data);
49353887Smckusick 		break;
49453887Smckusick 	case FBIOCSETCURSOR:
49553887Smckusick 		fbsetcursor(fbp, (sCursor *)data);
49653887Smckusick 		break;
49753887Smckusick 	case FBIOCNSETCURSOR:
49853887Smckusick 		fbnsetcursor(fbp, (lCursor *)data);
49953887Smckusick 		break;
50053887Smckusick 	case FBIOCNSETCURSOR2:
50153887Smckusick 		fbp->fb_command = FB_CSETCURSOR;
50253887Smckusick 		fbp->fb_cursor = *((lCursor2 *)data);
50353887Smckusick 		fbstart(fbp, 0);
50453887Smckusick 		break;
50553887Smckusick 	case FBIOCUNSETCURSOR:
50653887Smckusick 		fbp->fb_command = FB_CUNSETCURSOR;
50753887Smckusick 		fbstart(fbp, 0);
50853887Smckusick 		break;
50953887Smckusick 	case FBIOCNUNSETCURSOR:
51053887Smckusick 		fbp->fb_command = FB_CUNSETCURSOR;
51153887Smckusick 		fbstart(fbp, 0);
51253887Smckusick 		break;
51353887Smckusick 	case FBIOCSHOWCURSOR:
51453887Smckusick 		fbp->fb_command = FB_CSHOWCURSOR;
51553887Smckusick 		fbstart(fbp, 0);
51653887Smckusick 		break;
51753887Smckusick 	case FBIOCNSHOWCURSOR:
51853887Smckusick 		fbp->fb_command = FB_CSHOWCURSOR;
51953887Smckusick 		fbstart(fbp, 0);
52053887Smckusick 		break;
52153887Smckusick 	case FBIOCHIDECURSOR:
52253887Smckusick 		fbp->fb_command = FB_CHIDECURSOR;
52353887Smckusick 		fbstart(fbp, 0);
52453887Smckusick 		break;
52553887Smckusick 	case FBIOCNHIDECURSOR:
52653887Smckusick 		fbp->fb_command = FB_CHIDECURSOR;
52753887Smckusick 		fbstart(fbp, 0);
52853887Smckusick 		break;
52953887Smckusick 	case FBIOCSETXY:
53053887Smckusick 		fbsetxy(fbp, (sPoint *)data);
53153887Smckusick 		break;
53253887Smckusick 	case FBIOCNSETXY:
53353887Smckusick 		fbp->fb_command = FB_CSETXY;
53453887Smckusick 		fbp->fb_point = *((lPoint *)data);
53553887Smckusick 		fbstart(fbp, 0);
53653887Smckusick 		break;
53753887Smckusick 	case FBIOCNSETPALETTEMODE:
53853887Smckusick 		fbp->fb_command = FB_CSETPMODE;
53953887Smckusick 		fbp->fb_data = *((int*)data);
54053887Smckusick 		fbstart(fbp, 0);
54153887Smckusick 		break;
54253887Smckusick 	case FBIOCNGETPALETTEMODE:
54353887Smckusick 		fbp->fb_command = FB_CGETPMODE;
54453887Smckusick 		fbstart(fbp, 1);
54553887Smckusick 		*((int*)data) = fbp->fb_data;
54653887Smckusick 		break;
54753887Smckusick 	case FBIOCNSETVIDEO:
54853887Smckusick 		fbp->fb_command = FB_CSETVIDEO;
54953887Smckusick 		fbp->fb_videoctl = *((lVideoCtl*)data);
55053887Smckusick 		fbstart(fbp, 0);
55153887Smckusick 		break;
55253887Smckusick 	case FBIOCNGETVIDEO:
55353887Smckusick 		fbp->fb_command = FB_CGETVIDEO;
55453887Smckusick 		fbp->fb_videostatus.request = VIDEO_STATUS;
55553887Smckusick 		fbstart(fbp, 1);
55653887Smckusick 		*((lVideoStatus*)data) = fbp->fb_videostatus;
55753887Smckusick 		error = fbp->fb_result;
55853887Smckusick 		break;
55953887Smckusick 	case FBIOCNIOCTL:
56053887Smckusick 		fbp->fb_command = FB_CIOCTL;
56153887Smckusick 		fbp->fb_fbioctl = *((lFbIoctl*)data);
56253887Smckusick 		fbstart(fbp, 1);
56353887Smckusick 		*((lFbIoctl*)data) = fbp->fb_fbioctl;
56453887Smckusick 		if (fbp->fb_result == FB_RERROR)
56553887Smckusick 			error = EINVAL;
56653887Smckusick 		break;
56753887Smckusick 
56853887Smckusick 	default:
56953887Smckusick 		error = ENXIO;
57053887Smckusick 		break;
57153887Smckusick 	}
57253887Smckusick 
57353887Smckusick 	fbunlock(error);
57453887Smckusick 
57553887Smckusick 	return (error);
57653887Smckusick }
57753887Smckusick 
fbmmap(dev,off,prot)57853887Smckusick fbmmap(dev, off, prot)
57953887Smckusick 	dev_t dev;
58053887Smckusick 	off_t off;
58153887Smckusick 	int prot;
58253887Smckusick {
58353887Smckusick 	register int unit = FBUNIT(dev);
58453887Smckusick 	register struct fb_softc *fb = &fb_softc[unit];
58553887Smckusick 	register struct iop_device *ii;
58653887Smckusick 	register int page;
58753887Smckusick 	register struct fbreg *fbp = &fbreg[unit];
58853887Smckusick 
58953887Smckusick 	if (unit >= NFB || (ii = fbinfo[unit]) == 0 || ii->ii_alive == 0)
59053887Smckusick 		return (-1);
59153887Smckusick 
59253887Smckusick 	fblock();
59353887Smckusick 	fbp->fb_device = fb->fbs_device;
59453887Smckusick 	fbp->fb_command = FB_CGETPAGE;
59553887Smckusick 	fbp->fb_data = off;
59653887Smckusick 	fbstart(fbp, 1);
59753887Smckusick 	page = fbp->fb_data;
59853887Smckusick 	if (fbp->fb_result == FB_RERROR)
59953887Smckusick 		page = -1;
60053887Smckusick 	else
60153887Smckusick 		fb->fbs_flag = 1;
60253887Smckusick 	fbunlock(fbp->fb_result);
60353887Smckusick 
60453887Smckusick 	return (page);
60553887Smckusick }
60653887Smckusick 
60753887Smckusick static void
fblock()60853887Smckusick fblock()
60953887Smckusick {
61053887Smckusick 	int s;
61153887Smckusick 
61253887Smckusick #ifdef USE_RAW_INTR
61353887Smckusick 	fbwait();
61453887Smckusick #endif
61553887Smckusick 	s = splfb();
61653887Smckusick 	while (fbstate & FB_BUSY) {
61753887Smckusick 		fbstate |= FB_WANTED;
61853887Smckusick 		sleep((caddr_t)&fbstate, FBPRI);
61953887Smckusick 	}
62053887Smckusick 	fbstate |= FB_BUSY;
62153887Smckusick 	splx(s);
62253887Smckusick }
62353887Smckusick 
62453887Smckusick static void
fbunlock(error)62553887Smckusick fbunlock(error)
62653887Smckusick 	int error;
62753887Smckusick {
62853887Smckusick 	int s = splfb();
62953887Smckusick 
63053887Smckusick #ifdef CPU_SINGLE
63153887Smckusick 	fbstate &= ~FB_BUSY;
63253887Smckusick 	if (fbstate & FB_WANTED) {
63353887Smckusick 		fbstate &= ~FB_WANTED;
63453887Smckusick 		wakeup((caddr_t)&fbstate);
63553887Smckusick 	}
63653887Smckusick #else
63753887Smckusick #ifdef USE_RAW_INTR
63853887Smckusick 	fbstate &= ~FB_BUSY;
63953887Smckusick 	if (fbstate & FB_WANTED) {
64053887Smckusick 		fbstate &= ~FB_WANTED;
64153887Smckusick 		wakeup((caddr_t)&fbstate);
64253887Smckusick 	}
64353887Smckusick #else
64453887Smckusick 	if (error || (fbstate & FB_DELAY) == 0) {
64553887Smckusick 		fbstate &= ~(FB_BUSY | FB_WAIT | FB_DELAY);
64653887Smckusick 		if (fbstate & FB_WANTED) {
64753887Smckusick 			fbstate &= ~FB_WANTED;
64853887Smckusick 			wakeup((caddr_t)&fbstate);
64953887Smckusick 		}
65053887Smckusick 	}
65153887Smckusick 	if (fbstate & FB_DELAY) {
65253887Smckusick 		fbstate &= ~FB_DELAY;
65353887Smckusick 		fbstate |= FB_DELAY2;
65453887Smckusick 	}
65553887Smckusick #endif
65653887Smckusick #endif /* CPU_SINGLE */
65753887Smckusick 	splx(s);
65853887Smckusick }
65953887Smckusick 
66053887Smckusick static int
fbinit(fbp)66153887Smckusick fbinit(fbp)
66253887Smckusick 	struct fbreg *fbp;
66353887Smckusick {
66453887Smckusick 	fblock();
66553887Smckusick 
66653887Smckusick 	fbp->fb_command = FB_COPEN;
66753887Smckusick 	fbstart(fbp, 1);
66853887Smckusick 	if (fbp->fb_result != FB_ROK) {
66953887Smckusick 		fbunlock(0);
67053887Smckusick 		return (FB_RERROR);
67153887Smckusick 	}
67253887Smckusick 
67353887Smckusick 	fbp->fb_command = FB_CUNSETCURSOR;
67453887Smckusick 	fbstart(fbp, 0);
67553887Smckusick 
67653887Smckusick 	fbunlock(0);
67753887Smckusick 
67853887Smckusick 	return (FB_ROK);
67953887Smckusick }
68053887Smckusick 
68153887Smckusick static void
fbreset(fbp)68253887Smckusick fbreset(fbp)
68353887Smckusick 	struct fbreg *fbp;
68453887Smckusick {
68553887Smckusick 	fblock();
68653887Smckusick 
68753887Smckusick 	fbp->fb_command = FB_CUNSETCURSOR;
68853887Smckusick 	fbstart(fbp, 1);
68953887Smckusick 
69053887Smckusick 	fbp->fb_command = FB_CCLOSE;
69153887Smckusick 	fbstart(fbp, 0);
69253887Smckusick 
69353887Smckusick 	fbunlock(0);
69453887Smckusick }
69553887Smckusick #endif /* NFB */
696