patch-2.1.111 linux/drivers/video/sbusfb.c

Next file: linux/drivers/video/sbusfb.h
Previous file: linux/drivers/video/retz3fb.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.110/linux/drivers/video/sbusfb.c linux/drivers/video/sbusfb.c
@@ -52,7 +52,6 @@
 
 static int currcon;
 static int defx_margin = -1, defy_margin = -1;
-static int disable __initdata = 0;
 static char fontname[40] __initdata = { 0 };
 static struct {
 	int depth;
@@ -156,6 +155,13 @@
 	return 0;
 }
 
+static unsigned long sbusfb_mmapsize(struct fb_info_sbusfb *fb, long size)
+{
+	if (size == SBUS_MMAP_EMPTY) return 0;
+	if (size >= 0) return size;
+	return fb->type.fb_size * (-size);
+}
+
 static int sbusfb_mmap(struct fb_info *info, struct file *file, 
 			struct vm_area_struct *vma)
 {
@@ -174,7 +180,7 @@
 #ifdef __sparc_v9__
 	/* Align it as much as desirable */
 	{
-		int j, max = -1, alignment;
+		int j, max = -1, alignment, s = 0;
 		
 		map_offset = vma->vm_offset+size;
 		for (i = 0; fb->mmap_map[i].size; i++) {
@@ -182,11 +188,13 @@
 				continue;
 			if (fb->mmap_map[i].voff >= map_offset)
 				break;
-			if (max < 0 || fb->mmap_map[i].size > fb->mmap_map[max].size)
+			if (max < 0 || sbusfb_mmapsize(fb,fb->mmap_map[i].size) > s) {
 				max = i;
+				s = sbusfb_mmapsize(fb,fb->mmap_map[max].size);
+			}
 		}
 		if (max >= 0) {
-			j = fb->mmap_map[max].size;
+			j = s;
 			if (fb->mmap_map[max].voff + j > map_offset)
 				j = map_offset - fb->mmap_map[max].voff;
 			for (alignment = 0x400000; alignment > PAGE_SIZE; alignment >>= 3)
@@ -212,8 +220,8 @@
 		map_size = 0;
 		for (i = 0; fb->mmap_map[i].size; i++)
 			if (fb->mmap_map[i].voff == vma->vm_offset+page) {
-				map_size = fb->mmap_map[i].size;
-				map_offset = (fb->physbase + fb->mmap_map[i].poff) & _PAGE_PADDR;
+				map_size = sbusfb_mmapsize(fb,fb->mmap_map[i].size);
+				map_offset = (fb->physbase + fb->mmap_map[i].poff) & PAGE_MASK;
 				break;
 			}
 		if (!map_size){
@@ -232,10 +240,14 @@
 	file->f_count++;
 	vma->vm_flags |= VM_IO;
 	if (!fb->mmaped) {
+		int lastconsole = 0;
+		
+		if (info->display_fg)
+			lastconsole = info->display_fg->vc_num;
 		fb->mmaped = 1;
-		if (fb->consolecnt && fb_display[fb->lastconsole].fb_info == info) {
-			fb->vtconsole = fb->lastconsole;
-			vt_cons [fb->lastconsole]->vc_mode = KD_GRAPHICS;
+		if (fb->consolecnt && fb_display[lastconsole].fb_info == info) {
+			fb->vtconsole = lastconsole;
+			vt_cons [lastconsole]->vc_mode = KD_GRAPHICS;
 		} else if (fb->unblank && !fb->blanked)
 			(*fb->unblank)(fb);
 	}
@@ -520,6 +532,7 @@
 {
 	struct fb_info_sbusfb *fb = sbusfbinfo(info);
 	int i;
+	int lastconsole;
 	
 	switch (cmd){
 	case FBIOGTYPE:		/* return frame buffer type */
@@ -546,9 +559,11 @@
 		if (i) return i;
 		return -EINVAL;
 	case FBIOSVIDEO:
-		if (fb->consolecnt &&
-		    vt_cons[fb->lastconsole]->vc_mode == KD_TEXT)
- 			break;
+		if (fb->consolecnt) {
+			lastconsole = info->display_fg->vc_num;
+			if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
+ 				break;
+ 		}
 		get_user_ret(i, (int *)arg, -EFAULT);
 		if (i){
 			if (!fb->blanked || !fb->unblank)
@@ -643,7 +658,8 @@
 	case FBIOSCURSOR:
 		if (!fb->setcursor) return -EINVAL;
  		if (fb->consolecnt) {
- 			if (vt_cons[fb->lastconsole]->vc_mode == KD_TEXT)
+ 			lastconsole = info->display_fg->vc_num; 
+ 			if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
  				return -EINVAL; /* Don't let graphics programs hide our nice text cursor */
 			fb->hw_cursor_shown = 0; /* Forget state of our text cursor */
 		}
@@ -653,7 +669,8 @@
 		if (!fb->setcursor) return -EINVAL;
 		/* Don't let graphics programs move our nice text cursor */
  		if (fb->consolecnt) {
- 			if (vt_cons[fb->lastconsole]->vc_mode == KD_TEXT)
+ 			lastconsole = info->display_fg->vc_num; 
+ 			if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
  				return -EINVAL; /* Don't let graphics programs move our nice text cursor */
  		}
 		if (copy_from_user(&fb->cursor.cpos, (void *)arg, sizeof(struct fbcurpos)))
@@ -689,9 +706,7 @@
 			    	defx_margin = i; defy_margin = j;
 			    }
 			}
-		} else if (!strncmp(p, "disable", 7))
-			disable = 1;
-		else if (!strncmp(p, "font=", 5)) {
+		} else if (!strncmp(p, "font=", 5)) {
 			int i;
 			
 			for (i = 0; i < sizeof(fontname) - 1; i++)
@@ -710,16 +725,17 @@
 {
 	int x_margin, y_margin;
 	struct fb_info_sbusfb *fb = sbusfbinfo(info);
+	int lastconsole;
     
 	/* Do we have to save the colormap? */
 	if (fb_display[currcon].cmap.len)
 		fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1, sbusfb_getcolreg, info);
 
-	if (fb->lastconsole != con && 
-	    (fb_display[fb->lastconsole].fontwidth != fb_display[con].fontwidth ||
-	     fb_display[fb->lastconsole].fontheight != fb_display[con].fontheight))
+	lastconsole = info->display_fg->vc_num;
+	if (lastconsole != con && 
+	    (fb_display[lastconsole].fontwidth != fb_display[con].fontwidth ||
+	     fb_display[lastconsole].fontheight != fb_display[con].fontheight))
 		fb->hw_cursor_shown = 0;
-	fb->lastconsole = con;
 	x_margin = (fb_display[con].var.xres_virtual - fb_display[con].var.xres) / 2;
 	y_margin = (fb_display[con].var.yres_virtual - fb_display[con].var.yres) / 2;
 	if (fb->margins)
@@ -855,9 +871,33 @@
 	return 1;
 }
 
+void sbusfb_palette(int enter)
+{
+	int i;
+	struct display *p;
+	
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		p = &fb_display[i];
+		if (p->dispsw && p->dispsw->setup == sbusfb_disp_setup &&
+		    p->fb_info->display_fg &&
+		    p->fb_info->display_fg->vc_num == i) {
+			struct fb_info_sbusfb *fb = sbusfbinfod(p);
+
+			if (fb->restore_palette) {
+				if (enter)
+					fb->restore_palette(fb);
+				else if (vt_cons[i]->vc_mode != KD_GRAPHICS)
+				         vc_cons[i].d->vc_sw->con_set_palette(vc_cons[i].d, color_table);
+			}
+		}
+	}
+}
+
     /*
      *  Initialisation
      */
+     
+extern void (*prom_palette)(int);
 
 __initfunc(static void sbusfb_init_fb(int node, int parent, int fbtype,
 				      struct linux_sbus_device *sbdp))
@@ -876,6 +916,10 @@
 		prom_printf("Could not allocate sbusfb structure\n");
 		return;
 	}
+	
+	if (!prom_palette)
+		prom_palette = sbusfb_palette;
+	
 	memset(fb, 0, sizeof(struct fb_info_sbusfb));
 	fix = &fb->fix;
 	var = &fb->var;
@@ -893,7 +937,7 @@
 	fb->emulations[0] = fbtype;
 	
 #ifndef __sparc_v9__
-	disp->screen_base = prom_getintdefault(node, "address", 0);
+	disp->screen_base = (unsigned char *)prom_getintdefault(node, "address", 0);
 #endif
 	
 	type->fb_height = h = prom_getintdefault(node, "height", 900);
@@ -991,6 +1035,7 @@
 	fb->dispsw.set_font = sbusfb_set_font;
 	fb->setup = fb->dispsw.setup;
 	fb->dispsw.setup = sbusfb_disp_setup;
+	fb->dispsw.clear_margins = NULL;
 
 	disp->var = *var;
 	disp->visual = fix->visual;
@@ -1015,47 +1060,53 @@
 	char *p;
 	for (p = name; *p && *p != ','; p++);
 	if (*p == ',') name = p + 1;
-	if (!strcmp(p, "cgsix") || !strcmp(p, "cgthree+"))
+	if (!strcmp(name, "cgsix") || !strcmp(name, "cgthree+"))
 		return FBTYPE_SUNFAST_COLOR;
-	if (!strcmp(p, "cgthree") || !strcmp(p, "cgRDI"))
+	if (!strcmp(name, "cgthree") || !strcmp(name, "cgRDI"))
 		return FBTYPE_SUN3COLOR;
-	if (!strcmp(p, "cgfourteen"))
+	if (!strcmp(name, "cgfourteen"))
 		return FBTYPE_MDICOLOR;
-	if (!strcmp(p, "leo"))
+	if (!strcmp(name, "leo"))
 		return FBTYPE_SUNLEO;
-	if (!strcmp(p, "bwtwo"))
+	if (!strcmp(name, "bwtwo"))
 		return FBTYPE_SUN2BW;
-	if (!strcmp(p, "tcx"))
+	if (!strcmp(name, "tcx"))
 		return FBTYPE_TCXCOLOR;
 	return FBTYPE_NOTYPE;
 }
 
 __initfunc(void sbusfb_init(void))
 {
-	int node, root, type;
+	int type;
 	struct linux_sbus_device *sbdp;
 	struct linux_sbus *sbus;
 	char prom_name[40];
 	extern int con_is_present(void);
 	
-	if (!con_is_present() || disable) return;
+	if (!con_is_present()) return;
 	
 #ifdef CONFIG_FB_CREATOR
-	root = prom_getchild(prom_root_node);
-	for (node = prom_searchsiblings(root, "SUNW,ffb"); node;
-	     node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb")) {
-		sbusfb_init_fb(node, prom_root_node, FBTYPE_CREATOR, NULL);
+	{
+		int root, node;
+		root = prom_getchild(prom_root_node);
+		for (node = prom_searchsiblings(root, "SUNW,ffb"); node;
+		     node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb")) {
+			sbusfb_init_fb(node, prom_root_node, FBTYPE_CREATOR, NULL);
+		}
 	}
 #endif
 #ifdef CONFIG_SUN4
 	sbusfb_init_fb(0, 0, FBTYPE_SUN2BW, NULL);
 #endif
 #if defined(CONFIG_FB_CGFOURTEEN) && !defined(__sparc_v9__)
-	root = prom_getchild(prom_root_node);
-	root = prom_searchsiblings(root, "obio");
-	if (root && 
-	    (node = prom_searchsiblings(prom_getchild(root), "cgfourteen"))) {
-		sbusfb_init_fb(node, root, FBTYPE_MDICOLOR, NULL);
+	{
+		int root, node;
+		root = prom_getchild(prom_root_node);
+		root = prom_searchsiblings(root, "obio");
+		if (root && 
+		    (node = prom_searchsiblings(prom_getchild(root), "cgfourteen"))) {
+			sbusfb_init_fb(node, root, FBTYPE_MDICOLOR, NULL);
+		}
 	}
 #endif
 	if (!SBus_chain) return;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov