--- linux-2.2.16-pristine/drivers/video/fbmem.c Fri May 5 14:55:01 2000 +++ linux-2.2.16/drivers/video/fbmem.c Sat Aug 19 18:45:44 2000 @@ -214,7 +214,7 @@ static int last_fb_vc = MAX_NR_CONSOLES-1; static int fbcon_is_default = 1; -static int PROC_CONSOLE(struct fb_info *info) +int PROC_CONSOLE(struct fb_info *info) { int fgc; --- linux-2.2.16-pristine/include/video/fbcon.h Thu Feb 25 19:02:12 1999 +++ linux-2.2.16/include/video/fbcon.h Sat Aug 19 18:39:10 2000 @@ -40,6 +40,7 @@ }; extern struct display_switch fbcon_dummy; +extern int PROC_CONSOLE(const struct fb_info *info); #define fontheight(p) ((p)->_fontheight) #define fontheightlog(p) ((p)->_fontheightlog) --- linux-2.2.16-pristine/drivers/video/controlfb.c Wed Sep 15 07:48:12 1999 +++ linux-2.2.16/drivers/video/controlfb.c Sat Aug 19 18:46:19 2000 @@ -126,6 +126,8 @@ struct fb_info *info); static int control_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg, int con, struct fb_info *info); +static int control_mmap(struct fb_info *info, struct file *file, + struct vm_area_struct *vma); static int controlfb_getcolreg(u_int regno, u_int *red, u_int *green, @@ -178,7 +180,8 @@ control_get_cmap, control_set_cmap, control_pan_display, - control_ioctl + control_ioctl, + control_mmap }; @@ -356,6 +359,54 @@ u_long arg, int con, struct fb_info *info) { return -EINVAL; +} + +/* Private mmap since we want to have a different caching on the framebuffer + * for controlfb. + * Note there's no locking in here; it's done in fb_mmap() in fbmem.c. + */ +static int control_mmap(struct fb_info *info, struct file *file, + struct vm_area_struct *vma) +{ + struct fb_ops *fb = info->fbops; + struct fb_fix_screeninfo fix; + struct fb_var_screeninfo var; + unsigned long start; + u32 len; + + fb->fb_get_fix(&fix, PROC_CONSOLE(info), info); +printk(KERN_INFO "controlfb: Yeah, using new mmap!!\n"); + + /* frame buffer memory */ + start = (unsigned long)fix.smem_start; + len = (start & ~PAGE_MASK)+fix.smem_len; + len = (len+~PAGE_MASK) & PAGE_MASK; + if (vma->vm_offset >= len) { + /* memory mapped io */ + vma->vm_offset -= len; + fb->fb_get_var(&var, PROC_CONSOLE(info), info); + if (var.accel_flags) + return -EINVAL; + start = (unsigned long)fix.mmio_start; + len = (start & ~PAGE_MASK)+fix.mmio_len; + len = (len+~PAGE_MASK) & PAGE_MASK; + pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED; + } else { + /* framebuffer */ + pgprot_val(vma->vm_page_prot) |= _PAGE_WRITETHRU; + } + start &= PAGE_MASK; + if ((vma->vm_end - vma->vm_start + vma->vm_offset) > len) + return -EINVAL; + vma->vm_offset += start; + if (vma->vm_offset & ~PAGE_MASK) + return -ENXIO; + + if (remap_page_range(vma->vm_start, vma->vm_offset, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) + return -EAGAIN; + + return 0; } /******************** End of controlfb_ops implementation ********************/