From: Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
Date: Mon, 16 Jun 97 10:42:50 +0200
To: linux-m68k@phil.uni-sb.de
In-Reply-To: 
	<Pine.LNX.3.96.970613090701.20307A-100000@mercator.cs.kuleuven.ac.be>
	(message from Geert Uytterhoeven on Fri, 13 Jun 1997 09:10:06 +0200
	(MET DST))
Subject: Re: L68K: Frame buffer patches
X-Yow: I just had my entire INTESTINAL TRACT coated with TEFLON!
Sender: owner-linux-m68k@phil.uni-sb.de
Reply-To: linux-m68k@phil.uni-sb.de

Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be> writes:

|> Finally I ported the multiple/loadable frame buffer code to 2.1.42. The patch
|> should be applied after my abstract console patch.

Below is a patch to fix a few things.

- atafb.h is not used by anything and can be removed.
- never change the meaning of ioctl's, even if they were never used.  If
  you really want to change them do it right and use the macros from
  <linux/ioctl.h>.
- atari_fb_init: fix order of initialisations
- fbcon_setup: change p->dispsw atomically, it might be the current console
- remove arch/m68k/console from the list of build directories (and the
  directory can be removed, too)
- a proc interface for fbmem; more information could be printed here
- it would be nice if fbcon drivers had a name, which could be used for
  another proc interface
- fix the selection cursor colour
- fix resource leak on deallocating consoles

|>  - The utility `con2fbmap' allows you to dynamically map a virtual console to
|>    a frame buffer device.

You left out <errno.h> again.  Glibc doesn't forgive anything :-)

|> TODO:

|>   - Test atafb

Done.

|>  - Move the external video driver of atafb to a separate frame buffer device.

Perhaps even better: split it into drivers for TT, Falcon, STE and
external.

Andreas.

------------------------------------------------------------
--- arch/m68k/Makefile.~2~	Thu May 15 13:13:47 1997
+++ arch/m68k/Makefile	Sun Jun 15 11:51:34 1997
@@ -63,12 +63,6 @@
 SUBDIRS := $(SUBDIRS) arch/m68k/mac
 endif
 
-ifdef CONFIG_VT
-# add in console.a after {amiga,atari}.o that need it
-CORE_FILES := $(CORE_FILES) arch/m68k/console/console.a
-SUBDIRS := $(SUBDIRS) arch/m68k/console
-endif
-
 ifdef CONFIG_M68040
 CORE_FILES := $(CORE_FILES) arch/m68k/fpsp040/fpsp.o
 SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040
--- drivers/char/console.c.~2~	Sun Jun 15 12:24:26 1997
+++ drivers/char/console.c	Sun Jun 15 23:23:24 1997
@@ -201,6 +201,11 @@
 
 extern int abscon_probe(unsigned long *kmem_start);
 extern void abscon_init(int currcons);
+static inline void abscon_deinit(int currcons)
+{
+    sw->con_deinit(vc_cons[currcons].d);
+}
+
 static inline void abscon_erase_to_dpy_end(int currcons)
 {
     if (currcons != fg_console)
@@ -590,6 +595,7 @@
 void vc_disallocate(unsigned int currcons)
 {
 	if (vc_cons_allocated(currcons)) {
+	    ABSCON(deinit(currcons));
 	    if (kmalloced)
 	      kfree_s(vc_scrbuf[currcons], screenbuf_size);
 	    if (currcons >= MIN_NR_CONSOLES)
@@ -1285,11 +1291,11 @@
 		oldx = (offset >> 1) % video_num_columns;
 		oldy = (offset >> 1) / video_num_columns;
 		if (can_do_color)
-			new = old ^ 0x6600;
+			new = old ^ 0x7700;
 		else
 			new = old ^ 0x800;
 #else /* !CONFIG_ABSTRACT_CONSOLE */
-		new = old ^ 0x6600;
+		new = old ^ 0x7700;
 #endif /* !CONFIG_ABSTRACT_CONSOLE */
 		scr_writew(new, p);
 		ABSCON(putc_attr(currcons, new, oldy, oldx, oldattr));
--- drivers/char/fbmem.c.~2~	Sun Jun 15 11:01:06 1997
+++ drivers/char/fbmem.c	Sun Jun 15 13:47:40 1997
@@ -19,6 +19,9 @@
 #include <linux/mman.h>
 #include <linux/tty.h>
 #include <linux/init.h>
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#endif
 #ifdef CONFIG_KERNELD
 #include <linux/kerneld.h>
 #endif
@@ -89,6 +92,24 @@
 	return MINOR(current->tty->device) - 1;
 }
 
+#ifdef CONFIG_PROC_FS
+static int fbmem_read_proc(char *buf, char **start, off_t offset,
+			   int len, int *eof, void *private)
+{
+	struct fb_info **fi;
+
+	len = 0;
+	for (fi = registered_fb; fi < &registered_fb[FB_MAX] && len < 4000; fi++)
+		if (*fi)
+			len += sprintf(buf + len, "%d %d %s\n",
+				       GET_FB_IDX((*fi)->node),
+				       GET_FB_VAR_IDX((*fi)->node),
+				       (*fi)->modename);
+	*start = buf + offset;
+	return len > offset ? len - offset : 0;
+}
+#endif
+
 static long 
 fb_read(struct inode *inode, struct file *file, char *buf, unsigned long count)
 {
@@ -428,9 +449,19 @@
 	return 0;
 }
 
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry *proc_fbmem;
+#endif
+
 __initfunc(void
 fbmem_init(void))
 {
+#ifdef CONFIG_PROC_FS
+	proc_fbmem = create_proc_entry("fb", 0, 0);
+	if (proc_fbmem)
+		proc_fbmem->read_proc = fbmem_read_proc;
+#endif
+
 	if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
 		printk("unable to get major %d for fb devs\n", FB_MAJOR);
 }
--- drivers/video/atafb.c.~1~	Sun Jun 15 11:04:21 1997
+++ drivers/video/atafb.c	Sun Jun 15 19:17:36 1997
@@ -2947,29 +2947,10 @@
 	int pad;
 	int detected_mode;
 	unsigned long mem_req;
-	struct fb_var_screeninfo *var;
 
 	if (!MACH_IS_ATARI)
 	        return -ENODEV;
 
-	strcpy(fb_info.modename, "Atari Builtin ");
-	fb_info.changevar = NULL;
-	fb_info.node = -1;
-	fb_info.fbops = &atari_fb_ops;
-	fb_info.fbvar_num = num_atari_fb_predefined;
-	fb_info.fbvar = atari_fb_predefined;
-	fb_info.disp=&disp;
-	fb_info.switch_con=&atafb_switch;
-	fb_info.updatevar=&fb_update_var;
-	fb_info.blank=&atafb_blank;
-	fb_info.setcmap=&atafb_setcmap;
-	var=atari_fb_predefined+default_par-1;
-	do_fb_set_var(var,1);
-	strcat(fb_info.modename,fb_var_names[default_par-1][0]);
-
-	err=register_framebuffer(&fb_info);
-	if (err < 0)
-		return(err);
 	do {
 #ifdef ATAFB_EXT
 		if (external_addr) {
@@ -3046,10 +3027,28 @@
 	}
 #endif /* ATAFB_EXT */
 
-	atari_fb_get_var(&fb_display[0].var, -1);
+	strcpy(fb_info.modename, "Atari Builtin ");
+	fb_info.changevar = NULL;
+	fb_info.node = -1;
+	fb_info.fbops = &atari_fb_ops;
+	fb_info.fbvar_num = num_atari_fb_predefined;
+	fb_info.fbvar = atari_fb_predefined;
+	fb_info.disp = &disp;
+	fb_info.switch_con = &atafb_switch;
+	fb_info.updatevar = &fb_update_var;
+	fb_info.blank = &atafb_blank;
+	fb_info.setcmap = &atafb_setcmap;
+	do_fb_set_var(&atari_fb_predefined[default_par-1], 1);
+	strcat(fb_info.modename, fb_var_names[default_par-1][0]);
+
+	err=register_framebuffer(&fb_info);
+	if (err < 0)
+		return(err);
+
+	atari_fb_get_var(&disp.var, -1);
 	atari_fb_set_disp(-1);
 	printk("Determined %dx%d, depth %d\n",
-	       fb_display[0].var.xres, fb_display[0].var.yres, fb_display[0].var.bits_per_pixel );
+	       disp.var.xres, disp.var.yres, disp.var.bits_per_pixel);
 	do_install_cmap(0);
 	printk("%s frame buffer device, using %dK of video memory\n",
 	       fb_info.modename, screen_len>>10);
--- drivers/video/fbcon.c.~1~	Sun Jun 15 11:13:40 1997
+++ drivers/video/fbcon.c	Sun Jun 15 23:23:17 1997
@@ -313,8 +313,12 @@
 static int fbcon_deinit(struct vc_data *conp)
 {
     int unit = conp->vc_num;
+    struct display *p = &fb_display[unit];
 
-    fb_display[unit].conp = 0;
+    if (p->dispsw)
+	p->dispsw->release();
+    p->dispsw = 0;
+    p->conp = 0;
     return(0);
 }
 
@@ -345,6 +349,7 @@
     struct display *p = &fb_display[con];
     struct vc_data *conp = p->conp;
     int nr_rows, nr_cols;
+    struct display_switch *old_dispsw, *new_dispsw;
 
     p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */
 
@@ -373,14 +378,18 @@
     p->vrows = p->var.yres_virtual/p->fontheight;
     conp->vc_can_do_color = p->var.bits_per_pixel != 1;
 
-    if (p->dispsw)
-	p->dispsw->release();
-    if (!(p->dispsw = fbcon_get_driver(p))) {
+    new_dispsw = fbcon_get_driver(p);
+    if (!new_dispsw) {
 	printk(KERN_WARNING "fbcon_setup: type %d (aux %d, depth %d) not "
 	       "supported\n", p->type, p->type_aux, p->var.bits_per_pixel);
 	dispsw_dummy.open(p);
-	p->dispsw = &dispsw_dummy;
+	new_dispsw = &dispsw_dummy;
     }
+    /* Be careful when changing dispsw, it might be the current console.  */
+    old_dispsw = p->dispsw;
+    p->dispsw = new_dispsw;
+    if (old_dispsw)
+	old_dispsw->release();
 
     if (setcol) {
 	p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
--- include/linux/fb.h.~2~	Sun Jun 15 11:27:42 1997
+++ include/linux/fb.h	Sun Jun 15 11:34:21 1997
@@ -17,12 +17,12 @@
 #define FBIOGETCMAP		0x4604
 #define FBIOPUTCMAP		0x4605
 #define FBIOPAN_DISPLAY         0x4606
-/* #define FBIOGET_MONITORSPEC	0x4607 */
-/* #define FBIOPUT_MONITORSPEC	0x4608 */
-/* #define FBIOSWITCH_MONIBIT	0x4609 */
-#define FBIOGET_CON2FBMAP	0x460A
-#define FBIOPUT_CON2FBMAP	0x460B
-/* 0x460C-0x4610 are defined below */
+/* 0x4607-0x460B are defined below */
+/* #define FBIOGET_MONITORSPEC	0x460C */
+/* #define FBIOPUT_MONITORSPEC	0x460D */
+/* #define FBIOSWITCH_MONIBIT	0x460E */
+#define FBIOGET_CON2FBMAP	0x460F
+#define FBIOPUT_CON2FBMAP	0x4610
 
 #define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
 #define FB_TYPE_PLANES			1	/* Non interleaved planes */
@@ -255,11 +255,11 @@
     *    Hardware Cursor
     */
 
-#define FBIOGET_FCURSORINFO     0x460C
-#define FBIOGET_VCURSORINFO     0x460D
-#define FBIOPUT_VCURSORINFO     0x460E
-#define FBIOGET_CURSORSTATE     0x460F
-#define FBIOPUT_CURSORSTATE     0x4610
+#define FBIOGET_FCURSORINFO     0x4607
+#define FBIOGET_VCURSORINFO     0x4608
+#define FBIOPUT_VCURSORINFO     0x4609
+#define FBIOGET_CURSORSTATE     0x460A
+#define FBIOPUT_CURSORSTATE     0x460B
 
 
 struct fb_fix_cursorinfo {
