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