Module Name:    src
Committed By:   phx
Date:           Sat Nov  7 14:29:10 UTC 2015

Modified Files:
        src/sys/arch/amiga/dev: grf.c grf_cv.c grf_cv3d.c grfvar.h
Removed Files:
        src/sys/arch/amiga/dev: grfws.h

Log Message:
Improved wscons support. Virtual screens are now working.


To generate a diff of this commit:
cvs rdiff -u -r1.62 -r1.63 src/sys/arch/amiga/dev/grf.c
cvs rdiff -u -r1.56 -r1.57 src/sys/arch/amiga/dev/grf_cv.c
cvs rdiff -u -r1.30 -r1.31 src/sys/arch/amiga/dev/grf_cv3d.c
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/amiga/dev/grfvar.h
cvs rdiff -u -r1.1 -r0 src/sys/arch/amiga/dev/grfws.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amiga/dev/grf.c
diff -u src/sys/arch/amiga/dev/grf.c:1.62 src/sys/arch/amiga/dev/grf.c:1.63
--- src/sys/arch/amiga/dev/grf.c:1.62	Fri Jul 25 08:10:31 2014
+++ src/sys/arch/amiga/dev/grf.c	Sat Nov  7 14:29:10 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: grf.c,v 1.62 2014/07/25 08:10:31 dholland Exp $ */
+/*	$NetBSD: grf.c,v 1.63 2015/11/07 14:29:10 phx Exp $ */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: grf.c,v 1.62 2014/07/25 08:10:31 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: grf.c,v 1.63 2015/11/07 14:29:10 phx Exp $");
 
 /*
  * Graphics display driver for the Amiga
@@ -76,7 +76,6 @@ __KERNEL_RCSID(0, "$NetBSD: grf.c,v 1.62
 #include <amiga/amiga/color.h>	/* DEBUG */
 #include <amiga/amiga/device.h>
 #include <amiga/dev/grfioctl.h>
-#include <amiga/dev/grfws.h>
 #include <amiga/dev/grfvar.h>
 #include <amiga/dev/itevar.h>
 #include <amiga/dev/kbdvar.h>
@@ -182,11 +181,11 @@ grfattach(device_t parent, device_t self
 	grfsp[gp->g_unit] = gp;
 
 	/*
-	 * find our major device number
+	 * find our major device number, make device
 	 */
 	maj = cdevsw_lookup_major(&grf_cdevsw);
-
 	gp->g_grfdev = makedev(maj, gp->g_unit);
+
 	if (self != NULL) {
 		printf(": width %d height %d", gp->g_display.gd_dwidth,
 		    gp->g_display.gd_dheight);
@@ -194,23 +193,25 @@ grfattach(device_t parent, device_t self
 			printf(" monochrome\n");
 		else
 			printf(" colors %d\n", gp->g_display.gd_colors);
+
 #if NWSDISPLAY > 0
-		vcons_init(&gp->g_vd, gp, gp->g_screens[0], gp->g_accessops);
+		vcons_init(&gp->g_vd, gp, gp->g_defaultscr, gp->g_accessops);
 		gp->g_vd.init_screen = grf_init_screen;
+
 		if (gp->g_flags & GF_CONSOLE) {
 			console_vcons.scr_flags |= VCONS_SCREEN_IS_STATIC;
 			vcons_init_screen(&gp->g_vd,
 			    &console_vcons, 1, &defattr);
-			gp->g_screens[0]->textops =
+			gp->g_defaultscr->textops =
 			    &console_vcons.scr_ri.ri_ops;
-			wsdisplay_cnattach(gp->g_screens[0],
+			wsdisplay_cnattach(gp->g_defaultscr,
 			    &console_vcons.scr_ri, 0, 0, defattr);
 			vcons_replay_msgbuf(&console_vcons);
 		}
 
 		/* attach wsdisplay */
 		wa.console = (gp->g_flags & GF_CONSOLE) != 0;
-		wa.scrdata = &gp->g_screenlist;
+		wa.scrdata = gp->g_scrlist;
 		wa.accessops = gp->g_accessops;
 		wa.accesscookie = &gp->g_vd;
 		config_found(self, &wa, wsemuldisplaydevprint);
@@ -477,16 +478,17 @@ grfcninit(struct consdev *cd)
 		gp = grfsp[unit];
 		if (gp != NULL && (gp->g_flags & GF_ALIVE)) {
 			gp->g_flags |= GF_CONSOLE;  /* we are console! */
-			gp->g_screens[0]->ncols = gp->g_display.gd_fbwidth /
-			    gp->g_screens[0]->fontwidth;
-			gp->g_screens[0]->nrows = gp->g_display.gd_fbheight /
-			    gp->g_screens[0]->fontheight;
+
+			gp->g_defaultscr->ncols = gp->g_display.gd_fbwidth /
+			    gp->g_defaultscr->fontwidth;
+			gp->g_defaultscr->nrows = gp->g_display.gd_fbheight /
+			    gp->g_defaultscr->fontheight;
 
 			ri = grf_setup_rasops(gp, &console_vcons);
 			console_vcons.scr_cookie = gp;
 			defattr = 0;  /* XXX */
 
-			wsdisplay_preattach(gp->g_screens[0], ri, 0, 0,
+			wsdisplay_preattach(gp->g_defaultscr, ri, 0, 0,
 			    defattr);
 #if NKBD > 0
 			/* tell kbd device it is used as console keyboard */
@@ -519,8 +521,8 @@ grf_setup_rasops(struct grf_softc *gp, s
 	scr->scr_flags |= VCONS_DONT_READ;
 	memset(ri, 0, sizeof(struct rasops_info));
 
-	ri->ri_rows = gp->g_screens[0]->nrows;
-	ri->ri_cols = gp->g_screens[0]->ncols;
+	ri->ri_rows = gp->g_defaultscr->nrows;
+	ri->ri_cols = gp->g_defaultscr->ncols;
 	ri->ri_hw = scr;
 	ri->ri_ops.cursor    = gp->g_emulops->cursor;
 	ri->ri_ops.mapchar   = gp->g_emulops->mapchar;
@@ -538,6 +540,66 @@ grf_setup_rasops(struct grf_softc *gp, s
 	return ri;
 }
 
+/*
+ * Called as fallback for ioctls which are not handled by the specific
+ * grf driver.
+ */
+int
+grf_wsioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
+{
+	struct wsdisplayio_fbinfo *iofbi;
+	struct wsdisplay_fbinfo *fbinfo;
+	struct vcons_data *vd;
+	struct grf_softc *gp;
+	struct vcons_screen *scr;
+	struct grfinfo *gi;
+
+	vd = v;
+	gp = vd->cookie;
+	scr = vd->active;
+
+	switch (cmd) {
+	case WSDISPLAYIO_GET_FBINFO:
+		if (scr != NULL) {
+			iofbi = data;
+			return wsdisplayio_get_fbinfo(&scr->scr_ri, iofbi);
+		}
+		return ENODEV;
+
+	case WSDISPLAYIO_GINFO:
+		if (scr != NULL) {
+			fbinfo = (struct wsdisplay_fbinfo *)data;
+			gi = &gp->g_display;
+
+			/*
+			 * We should return truth about the current mode here,
+			 * because X11 wsfb driver depends on this!
+			 */
+			fbinfo->height = gi->gd_fbheight;
+			fbinfo->width = gi->gd_fbwidth;
+			fbinfo->depth = gi->gd_planes;
+			fbinfo->cmsize = gi->gd_colors;
+			return 0;
+		}
+		return ENODEV;
+
+	case WSDISPLAYIO_GTYPE:
+		*(u_int *)data = WSDISPLAY_TYPE_GRF;
+		return 0;
+
+	case WSDISPLAYIO_SMODE:
+		if ((*(int *)data) != gp->g_wsmode) {
+			gp->g_wsmode = *(int *)data;
+			if (gp->g_wsmode == WSDISPLAYIO_MODE_EMUL &&
+			    scr != NULL)
+				vcons_redraw_screen(scr);
+		} 
+		return 0;
+	}
+
+	return EPASSTHROUGH;
+}
+
 paddr_t
 grf_wsmmap(void *v, void *vs, off_t off, int prot)
 {
@@ -582,236 +644,6 @@ grf_wsmmap_md(off_t off) 
 #endif
 }
 
-int
-grf_wsioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
-{
-	struct vcons_data *vd;
-	struct grf_softc *gp;
-
-	vd = v;
-	gp = vd->cookie;
-
-	switch (cmd) {
-	/* XXX: check if ptr to implementation is not null */
-	case WSDISPLAYIO_GINFO:
-		return gp->g_wsioctl->ginfo(gp, data);
-	case WSDISPLAYIO_SMODE:
-		return gp->g_wsioctl->smode(gp, data);
-	case WSDISPLAYIO_GMODE:
-		return gp->g_wsioctl->gmode(gp, data);
-	case WSDISPLAYIO_GTYPE:
-		return gp->g_wsioctl->gtype(gp, data);
-	case WSDISPLAYIO_SVIDEO:
-		return gp->g_wsioctl->svideo(gp, data);
-	case WSDISPLAYIO_GVIDEO:
-		return gp->g_wsioctl->gvideo(gp, data);
-	case WSDISPLAYIO_GETCMAP:
-		return gp->g_wsioctl->getcmap(gp, data);
-	case WSDISPLAYIO_PUTCMAP:
-		return gp->g_wsioctl->putcmap(gp, data);
-	}
-
-	return EPASSTHROUGH;
-}
-
-/* wsdisplay_accessops ioctls */
-
-int 
-grf_wsaogetcmap(void *c, void *data) 
-{
-	u_int index, count;
-	struct grf_softc *gp;
-	struct wsdisplay_cmap *cm __unused;
-
-	cm = (struct wsdisplay_cmap*) data;
-	gp = c;
-	index = 0;
-	count = 0;
-
-	if (gp->g_wsmode == WSDISPLAYIO_MODE_EMUL)
-		return EINVAL;
-
-	if (index >= 255 || count > 256 || index + count > 256)
-		return EINVAL;
-
-	/* 
-	 * TODO: copyout values for r, g, b. This function should be 
-	 * driver-specific... 
-	 */
-
-	return 0;
-}
-
-int
-grf_wsaoputcmap(void *c, void *data)
-{
-	/*
-	 * We probably couldn't care less about color map in MODE_EMUL,
-	 * I don't know about X11 yet. Also, these ioctls could be used by
-	 * fullscreen console programs (think wsdisplay picture viewer, or
-	 * the wsimgshow tool written by Yasushi Oshima).
-	 */
-	struct grf_softc *gp;
-
-	gp = c;
-
-	if (gp->g_wsmode == WSDISPLAYIO_MODE_EMUL)
-		return EINVAL;
-	/* ... */
-
-	return 0;
-}
-
-int
-grf_wsaosvideo(void *c, void *data)
-{
-#if 0
-	struct grf_softc *gp;
-	dev_t dev; 
-	int rv;
-
-	gp = c;
-	dev = (dev_t) &gp->g_grfdev;
-
-	if (*(u_int *)data == WSDISPLAYIO_VIDEO_OFF) {
-		if ((gp->g_flags & GF_GRFON) == 0)
-			rv = 0;
-		else {
-			gp->g_flags &= ~GF_GRFON;
-			rv = gp->g_mode(gp, (dev & GRFOVDEV) ? 
-			    GM_GRFOVOFF : GM_GRFOFF, NULL, 0, 0);
-		}
-
-	} else {
-		if ((gp->g_flags & GF_GRFON))
-        		rv = 0;
-		else
-			gp->g_flags |= GF_GRFON;
-			rv = gp->g_mode(gp, (dev & GRFOVDEV) ? 
-			    GM_GRFOVON : GM_GRFON, NULL, 0, 0);
-	}
-
-	return rv;
-#endif
-	return 0;
-}
-
-int
-grf_wsaogvideo(void *c, void *data) 
-{
-	struct grf_softc *gp;
-
-	gp = c;
-
-	if(gp->g_flags & GF_GRFON) 
-		*(u_int *)data = WSDISPLAYIO_VIDEO_ON;
-	else
-		*(u_int *)data = WSDISPLAYIO_VIDEO_OFF;
-
-	return 0;
-}
-
-int
-grf_wsaogtype(void *c, void *data)
-{
-	struct grf_softc *gp __unused;
-
-	gp = c;
-
-	*(u_int *)data = WSDISPLAY_TYPE_GRF;
-	return 0;
-}
-
-int
-grf_wsaogmode(void *c, void *data)
-{
-	struct grf_softc *gp;
-
-	gp = c;
-
-	*(u_int *)data = gp->g_wsmode;
-	return 0;
-}
-
-int
-grf_wsaosmode(void *c, void *data)
-{
-	/* XXX: should provide hw-dependent impl of this in grf_xxx driver? */
-	struct grf_softc *gp;
-
-	gp = c;
-
-	if ((*(int*) data) != gp->g_wsmode) {
-		gp->g_wsmode = (*(int*) data);
-		if ((*(int*) data) == WSDISPLAYIO_MODE_EMUL) {
-			//vcons_redraw_screen( active vcons screen );
-		} 
-	}
-	return 0;
-}
-
-int
-grf_wsaoginfo(void *c, void *data) 
-{
-	struct wsdisplay_fbinfo *fbinfo;
-	struct grf_softc *gp;
-	struct grfinfo *gi;
-
-	gp = c;
-
-	fbinfo = (struct wsdisplay_fbinfo *)data;
-	gi = &gp->g_display;
-
-	/*
-	 * TODO: better sanity checking, it is possible that 
-	 * wsdisplay is initialized, but no screen is opened
-	 * (for example, device is not used).
-	 */
-
-	/*
-	 * We shold return truth about current mode here because
-	 * X11 wsfb driver denepds on this!
-	 */
-	fbinfo->height = gi->gd_fbheight;
-	fbinfo->width = gi->gd_fbwidth;
-	fbinfo->depth = gi->gd_planes;
-	fbinfo->cmsize = gi->gd_colors;
-
-	return 0;
-}
-
 #endif  /* NWSDISPLAY > 0 */
 
-#ifdef DEBUG
-void
-grfdebug(struct grf_softc *gp, const char *fmt, ...)
-{
-	static int ccol = 0, crow = 1;
-	volatile char *cp;
-	char buf[256];
-	va_list ap;
-	int ncols;
-	char *bp;
-
-	va_start(ap, fmt);
-	vsnprintf(buf, 256, fmt, ap);
-	va_end(ap);
-
-	cp = gp->g_fbkva;
-	ncols = gp->g_display.gd_fbwidth / 8;
-	cp += (crow * ncols + ccol) << 2;
-	for (bp = buf; *bp != '\0'; bp++) {
-		if (*bp == '\n') {
-			ccol = 0;
-			crow++;
-			continue;
-		}
-		*cp++ = *bp;
-		*cp = 0x0a;
-		cp += 3;
-		ccol++;
-	}
-}
-#endif  /* DEBUG */
-
 #endif	/* NGRF > 0 */

Index: src/sys/arch/amiga/dev/grf_cv.c
diff -u src/sys/arch/amiga/dev/grf_cv.c:1.56 src/sys/arch/amiga/dev/grf_cv.c:1.57
--- src/sys/arch/amiga/dev/grf_cv.c:1.56	Wed Jan 22 00:25:16 2014
+++ src/sys/arch/amiga/dev/grf_cv.c	Sat Nov  7 14:29:10 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: grf_cv.c,v 1.56 2014/01/22 00:25:16 christos Exp $ */
+/*	$NetBSD: grf_cv.c,v 1.57 2015/11/07 14:29:10 phx Exp $ */
 
 /*
  * Copyright (c) 1995 Michael Teske
@@ -33,7 +33,7 @@
 #include "opt_amigacons.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: grf_cv.c,v 1.56 2014/01/22 00:25:16 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: grf_cv.c,v 1.57 2015/11/07 14:29:10 phx Exp $");
 
 #include "grfcv.h"
 #include "ite.h"
@@ -75,7 +75,6 @@ __KERNEL_RCSID(0, "$NetBSD: grf_cv.c,v 1
 #include <amiga/amiga/device.h>
 #include <amiga/amiga/isr.h>
 #include <amiga/dev/grfioctl.h>
-#include <amiga/dev/grfws.h>
 #include <amiga/dev/grfvar.h>
 #include <amiga/dev/grf_cvreg.h>
 #include <amiga/dev/zbusvar.h>
@@ -90,7 +89,8 @@ static unsigned short cv_compute_clock(u
 void	cv_boardinit(struct grf_softc *);
 int	cv_getvmode(struct grf_softc *, struct grfvideo_mode *);
 int	cv_setvmode(struct grf_softc *, unsigned int);
-int	cv_blank(struct grf_softc *, int *);
+int	cv_blank(struct grf_softc *, int);
+int	cv_isblank(struct grf_softc *);
 int	cv_mode(register struct grf_softc *, u_long, void *, u_long, int);
 int	cv_ioctl(register struct grf_softc *gp, u_long cmd, void *data);
 int	cv_setmonitor(struct grf_softc *, struct grfvideo_mode *);
@@ -270,6 +270,8 @@ long cv_memclk = 50000000;
 
 #if NWSDISPLAY > 0
 /* wsdisplay acessops, emulops */
+static int	cv_wsioctl(void *, void *, u_long, void *, int, struct lwp *);
+
 static void	cv_wscursor(void *, int, int, int);
 static void	cv_wsputchar(void *, int, int, u_int, long);
 static void	cv_wscopycols(void *, int, int, int, int);
@@ -280,7 +282,7 @@ static int	cv_wsallocattr(void *, int, i
 static int	cv_wsmapchar(void *, int, unsigned int *);
 
 static struct wsdisplay_accessops cv_accessops = {
-	.ioctl		= grf_wsioctl,
+	.ioctl		= cv_wsioctl,
 	.mmap		= grf_wsmmap
 };
 
@@ -295,18 +297,7 @@ static struct wsdisplay_emulops cv_texto
 	.allocattr	= cv_wsallocattr
 };
 
-static struct ws_ao_ioctl cv_wsioctl = {
-	grf_wsaoginfo,
-	grf_wsaogetcmap,
-	grf_wsaoputcmap,
-	grf_wsaogvideo,
-	grf_wsaosvideo,
-	grf_wsaogmode,
-	grf_wsaosmode,
-	grf_wsaogtype
-};
-
-static struct wsscreen_descr cv_screen = {
+static struct wsscreen_descr cv_defaultscreen = {
 	.name		= "default",
 	.textops	= &cv_textops,
 	.fontwidth	= 8,
@@ -314,6 +305,14 @@ static struct wsscreen_descr cv_screen =
 	.capabilities	= WSSCREEN_HILIT | WSSCREEN_BLINK |
 			  WSSCREEN_REVERSE | WSSCREEN_UNDERLINE
 };
+
+static const struct wsscreen_descr *cv_screens[] = {
+	&cv_defaultscreen,
+};
+
+static struct wsscreen_list cv_screenlist = {
+	sizeof(cv_screens) / sizeof(struct wsscreen_descr *), cv_screens
+};
 #endif  /* NWSDISPLAY > 0 */
 
 /* standard driver stuff */
@@ -540,9 +539,8 @@ grfcvattach(device_t parent, device_t se
 #if NWSDISPLAY > 0
 		gp->g_accessops = &cv_accessops;
 		gp->g_emulops = &cv_textops;
-		gp->g_defaultscreen = cv_screen;
-		gp->g_screens[0] = &gp->g_defaultscreen;
-		gp->g_wsioctl = &cv_wsioctl;
+		gp->g_defaultscr = &cv_defaultscreen;
+		gp->g_scrlist = &cv_screenlist;
 #else
 		grfcv_iteinit(gp);
 #endif
@@ -946,16 +944,28 @@ cv_setvmode(struct grf_softc *gp, unsign
 
 
 int
-cv_blank(struct grf_softc *gp, int *on)
+cv_blank(struct grf_softc *gp, int on)
 {
 	volatile void *ba;
 
 	ba = gp->g_regkva;
-	gfx_on_off(*on > 0 ? 0 : 1, ba);
+	gfx_on_off(on > 0 ? 0 : 1, ba);
 	return (0);
 }
 
 
+int
+cv_isblank(struct grf_softc *gp)
+{
+	volatile void *ba;
+	int r;
+
+	ba = gp->g_regkva;
+	r = RSeq(ba, SEQ_ID_CLOCKING_MODE);
+	return (r & 0x20) != 0;
+}
+
+
 /*
  * Change the mode of the display.
  * Return a UNIX error number or 0 for success.
@@ -1055,7 +1065,7 @@ cv_ioctl(register struct grf_softc *gp, 
 		return (cv_setmonitor (gp, (struct grfvideo_mode *)data));
 
 	    case GRFIOCBLANK:
-		return (cv_blank (gp, (int *)data));
+		return (cv_blank (gp, *(int *)data));
 	}
 	return (EPASSTHROUGH);
 }
@@ -2444,6 +2454,43 @@ cv_wsmapchar(void *c, int ch, unsigned i
 	return 0;
 }
 
+static int
+cv_wsioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
+{
+	struct vcons_data *vd;
+	struct grf_softc *gp;
+
+	vd = v;
+	gp = vd->cookie;
+
+	switch (cmd) {
+	case WSDISPLAYIO_GETCMAP:
+		/* Note: wsdisplay_cmap and grf_colormap have same format */
+		if (gp->g_display.gd_planes == 8)
+			return cv_getcmap(gp, (struct grf_colormap *)data);
+		return EINVAL;
+
+	case WSDISPLAYIO_PUTCMAP:
+		/* Note: wsdisplay_cmap and grf_colormap have same format */
+		if (gp->g_display.gd_planes == 8)
+			return cv_putcmap(gp, (struct grf_colormap *)data);
+		return EINVAL;
+
+	case WSDISPLAYIO_GVIDEO:
+		if (cv_isblank(gp))
+			*(u_int *)data = WSDISPLAYIO_VIDEO_OFF;
+		else
+			*(u_int *)data = WSDISPLAYIO_VIDEO_ON;
+		return 0;
+
+	case WSDISPLAYIO_SVIDEO:
+		return cv_blank(gp, *(u_int *)data == WSDISPLAYIO_VIDEO_OFF);
+	}
+
+	/* handle this command hw-independant in grf(4) */
+	return grf_wsioctl(v, vs, cmd, data, flag, l);
+}
+
 #endif  /* NWSDISPLAY > 0 */
 
 #endif  /* NGRFCV */

Index: src/sys/arch/amiga/dev/grf_cv3d.c
diff -u src/sys/arch/amiga/dev/grf_cv3d.c:1.30 src/sys/arch/amiga/dev/grf_cv3d.c:1.31
--- src/sys/arch/amiga/dev/grf_cv3d.c:1.30	Wed Jan 22 00:25:16 2014
+++ src/sys/arch/amiga/dev/grf_cv3d.c	Sat Nov  7 14:29:10 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: grf_cv3d.c,v 1.30 2014/01/22 00:25:16 christos Exp $ */
+/*	$NetBSD: grf_cv3d.c,v 1.31 2015/11/07 14:29:10 phx Exp $ */
 
 /*
  * Copyright (c) 1995 Michael Teske
@@ -33,7 +33,7 @@
 #include "opt_amigacons.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: grf_cv3d.c,v 1.30 2014/01/22 00:25:16 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: grf_cv3d.c,v 1.31 2015/11/07 14:29:10 phx Exp $");
 
 #include "ite.h"
 #include "wsdisplay.h"
@@ -99,7 +99,6 @@ Note: IO Regbase is needed fo wakeup of 
 #include <amiga/dev/itevar.h>
 #include <amiga/amiga/device.h>
 #include <amiga/dev/grfioctl.h>
-#include <amiga/dev/grfws.h>
 #include <amiga/dev/grfvar.h>
 #include <amiga/dev/grf_cv3dreg.h>
 #include <amiga/dev/zbusvar.h>
@@ -123,7 +122,8 @@ static unsigned short cv3d_compute_clock
 void	cv3d_boardinit(struct grf_softc *);
 int	cv3d_getvmode(struct grf_softc *, struct grfvideo_mode *);
 int	cv3d_setvmode(struct grf_softc *, unsigned int);
-int	cv3d_blank(struct grf_softc *, int *);
+int	cv3d_blank(struct grf_softc *, int);
+int	cv3d_isblank(struct grf_softc *);
 int	cv3d_mode(register struct grf_softc *, u_long, void *, u_long, int);
 int	cv3d_ioctl(register struct grf_softc *gp, u_long cmd, void *data);
 int	cv3d_setmonitor(struct grf_softc *, struct grfvideo_mode *);
@@ -290,6 +290,8 @@ long cv3d_memclk = 55000000;
 
 #if NWSDISPLAY > 0 
 /* wsdisplay accessops, emulops */
+static int	cv3d_wsioctl(void *, void *, u_long, void *, int, struct lwp *);
+
 static void	cv3d_wscursor(void *, int, int, int);
 static void	cv3d_wsputchar(void *, int, int, u_int, long);
 static void	cv3d_wscopycols(void *, int, int, int, int);
@@ -300,7 +302,7 @@ static int	cv3d_wsallocattr(void *, int,
 static int	cv3d_wsmapchar(void *, int, unsigned int *);
 
 struct wsdisplay_accessops cv3d_accessops = {
-	.ioctl		= grf_wsioctl,
+	.ioctl		= cv3d_wsioctl,
 	.mmap		= grf_wsmmap
 };
 
@@ -315,24 +317,21 @@ static struct wsdisplay_emulops cv3d_tex
 	.allocattr	= cv3d_wsallocattr
 };
 
-static struct ws_ao_ioctl cv3d_wsioctl = {
-	grf_wsaoginfo,
-	grf_wsaogetcmap,
-	grf_wsaoputcmap,
-	grf_wsaogvideo,
-	grf_wsaosvideo,
-	grf_wsaogmode,
-	grf_wsaosmode,
-	grf_wsaogtype
-};
-
-static struct wsscreen_descr cv3d_screen = {
+static struct wsscreen_descr cv3d_defaultscreen = {
 	.name		= "default",
 	.textops	= &cv3d_textops,
 	.fontwidth	= 8,
 	.fontheight	= S3FONTY,
-	.capabilities	= WSSCREEN_HILIT | WSSCREEN_REVERSE |
-			  WSSCREEN_BLINK | WSSCREEN_UNDERLINE
+	.capabilities	= WSSCREEN_HILIT | WSSCREEN_BLINK |
+			  WSSCREEN_REVERSE | WSSCREEN_UNDERLINE
+};
+
+static const struct wsscreen_descr *cv3d_screens[] = {
+	&cv3d_defaultscreen,
+};
+
+static struct wsscreen_list cv3d_screenlist = {
+	sizeof(cv3d_screens) / sizeof(struct wsscreen_descr *), cv3d_screens
 };
 #endif /* NWSDISPLAY > 0 */
 
@@ -487,12 +486,11 @@ grfcv3dattach(device_t parent, device_t 
 		cv3d_boardinit(gp);
 
 #ifdef CV3DCONSOLE
-#if NWSDISPLAY > 0 
+#if NWSDISPLAY > 0
 		gp->g_accessops = &cv3d_accessops;
 		gp->g_emulops = &cv3d_textops;
-		gp->g_defaultscreen = cv3d_screen;
-		gp->g_screens[0] = &gp->g_defaultscreen; 
-		gp->g_wsioctl = &cv3d_wsioctl;
+		gp->g_defaultscr = &cv3d_defaultscreen;
+		gp->g_scrlist = &cv3d_screenlist;
 #else
 		grfcv3d_iteinit(gp);
 #endif /* NWSDISPLAY > 0 */
@@ -867,16 +865,28 @@ cv3d_setvmode(struct grf_softc *gp, unsi
 
 
 int
-cv3d_blank(struct grf_softc *gp, int *on)
+cv3d_blank(struct grf_softc *gp, int on)
 {
 	volatile void *ba;
 
 	ba = gp->g_regkva;
-	cv3d_gfx_on_off(*on > 0 ? 0 : 1, ba);
+	cv3d_gfx_on_off(on > 0 ? 0 : 1, ba);
 	return (0);
 }
 
 
+int
+cv3d_isblank(struct grf_softc *gp)
+{
+	volatile void *ba;
+	int r;
+
+	ba = gp->g_regkva;
+	r = RSeq(ba, SEQ_ID_CLOCKING_MODE);
+	return (r & 0x20) != 0;
+}
+
+
 /*
  * Change the mode of the display.
  * Return a UNIX error number or 0 for success.
@@ -976,7 +986,7 @@ cv3d_ioctl(register struct grf_softc *gp
 		return (cv3d_setmonitor (gp, (struct grfvideo_mode *)data));
 
 	    case GRFIOCBLANK:
-		return (cv3d_blank (gp, (int *)data));
+		return (cv3d_blank (gp, *(int *)data));
 	}
 	return (EPASSTHROUGH);
 }
@@ -2299,6 +2309,43 @@ cv3d_wsallocattr(void *c, int fg, int bg
 	return 0;
 }
 
+static int
+cv3d_wsioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
+{
+	struct vcons_data *vd;
+	struct grf_softc *gp;
+
+	vd = v;
+	gp = vd->cookie;
+
+	switch (cmd) {
+	case WSDISPLAYIO_GETCMAP:
+		/* Note: wsdisplay_cmap and grf_colormap have same format */
+		if (gp->g_display.gd_planes == 8)
+			return cv3d_getcmap(gp, (struct grf_colormap *)data);
+		return EINVAL;
+
+	case WSDISPLAYIO_PUTCMAP:
+		/* Note: wsdisplay_cmap and grf_colormap have same format */
+		if (gp->g_display.gd_planes == 8)
+			return cv3d_putcmap(gp, (struct grf_colormap *)data);
+		return EINVAL;
+
+	case WSDISPLAYIO_GVIDEO:
+		if (cv3d_isblank(gp))
+			*(u_int *)data = WSDISPLAYIO_VIDEO_OFF;
+		else
+			*(u_int *)data = WSDISPLAYIO_VIDEO_ON;
+		return 0;
+
+	case WSDISPLAYIO_SVIDEO:
+		return cv3d_blank(gp, *(u_int *)data == WSDISPLAYIO_VIDEO_OFF);
+	}
+
+	/* handle this command hw-independant in grf(4) */
+	return grf_wsioctl(v, vs, cmd, data, flag, l);
+}
+
 #endif /* NWSDISPLAY > 0 */
 
 #endif  /* NGRFCV3D */

Index: src/sys/arch/amiga/dev/grfvar.h
diff -u src/sys/arch/amiga/dev/grfvar.h:1.24 src/sys/arch/amiga/dev/grfvar.h:1.25
--- src/sys/arch/amiga/dev/grfvar.h:1.24	Sat Oct 27 17:17:29 2012
+++ src/sys/arch/amiga/dev/grfvar.h	Sat Nov  7 14:29:10 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: grfvar.h,v 1.24 2012/10/27 17:17:29 chs Exp $	*/
+/*	$NetBSD: grfvar.h,v 1.25 2015/11/07 14:29:10 phx Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -66,11 +66,9 @@ struct	grf_softc {
 #if NWSDISPLAY > 0
 	struct wsdisplay_accessops	*g_accessops;
 	struct wsdisplay_emulops	*g_emulops;
-	struct wsscreen_descr		g_defaultscreen;
-	struct wsscreen_descr		*g_screens[1];
-	struct wsscreen_list		g_screenlist;
+	struct wsscreen_descr		*g_defaultscr;
+	struct wsscreen_list		*g_scrlist;
 	struct vcons_data		g_vd;
-	struct ws_ao_ioctl		*g_wsioctl;
 	uint16_t g_rowoffset[MAXROWS];	/* speed up putchar-multiplication */
 	int	g_wsmode;		/* current wsdisplay mode */ 
 	
@@ -84,6 +82,15 @@ struct	grf_softc {
 	void 	(*g_itescroll)(struct ite_softc *, int, int, int, int);
 #endif /* NWSDISPLAY */
 };
+
+#if NWSDISPLAY > 0
+/*
+ * Generic wsdisplay access ops that can be used from all grf drivers.
+ */
+paddr_t	grf_wsmmap(void *, void *, off_t, int);
+int	grf_wsioctl(void *, void *, u_long, void *, int, struct lwp *);
+#endif /* NWSDISPLAY */
+
 #endif /* _KERNEL */
 
 /* flags */

Reply via email to