?? fbmem.c
字號:
static int fbmem_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *private){ struct fb_info **fi; int clen; clen = 0; for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && clen < 4000; fi++) if (*fi) clen += sprintf(buf + clen, "%d %s\n", (*fi)->node, (*fi)->fix.id); *start = buf + offset; if (clen > offset) clen -= offset; else clen = 0; return clen < len ? clen : len;}static ssize_tfb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos){ unsigned long p = *ppos; struct inode *inode = file->f_path.dentry->d_inode; int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; u32 *buffer, *dst; u32 __iomem *src; int c, i, cnt = 0, err = 0; unsigned long total_size; if (!info || ! info->screen_base) return -ENODEV; if (info->state != FBINFO_STATE_RUNNING) return -EPERM; if (info->fbops->fb_read) return info->fbops->fb_read(info, buf, count, ppos); total_size = info->screen_size; if (total_size == 0) total_size = info->fix.smem_len; if (p >= total_size) return 0; if (count >= total_size) count = total_size; if (count + p > total_size) count = total_size - p; buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); if (!buffer) return -ENOMEM; src = (u32 __iomem *) (info->screen_base + p); if (info->fbops->fb_sync) info->fbops->fb_sync(info); while (count) { c = (count > PAGE_SIZE) ? PAGE_SIZE : count; dst = buffer; for (i = c >> 2; i--; ) *dst++ = fb_readl(src++); if (c & 3) { u8 *dst8 = (u8 *) dst; u8 __iomem *src8 = (u8 __iomem *) src; for (i = c & 3; i--;) *dst8++ = fb_readb(src8++); src = (u32 __iomem *) src8; } if (copy_to_user(buf, buffer, c)) { err = -EFAULT; break; } *ppos += c; buf += c; cnt += c; count -= c; } kfree(buffer); return (err) ? err : cnt;}static ssize_tfb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos){ unsigned long p = *ppos; struct inode *inode = file->f_path.dentry->d_inode; int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; u32 *buffer, *src; u32 __iomem *dst; int c, i, cnt = 0, err = 0; unsigned long total_size; if (!info || !info->screen_base) return -ENODEV; if (info->state != FBINFO_STATE_RUNNING) return -EPERM; if (info->fbops->fb_write) return info->fbops->fb_write(info, buf, count, ppos); total_size = info->screen_size; if (total_size == 0) total_size = info->fix.smem_len; if (p > total_size) return -EFBIG; if (count > total_size) { err = -EFBIG; count = total_size; } if (count + p > total_size) { if (!err) err = -ENOSPC; count = total_size - p; } buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); if (!buffer) return -ENOMEM; dst = (u32 __iomem *) (info->screen_base + p); if (info->fbops->fb_sync) info->fbops->fb_sync(info); while (count) { c = (count > PAGE_SIZE) ? PAGE_SIZE : count; src = buffer; if (copy_from_user(src, buf, c)) { err = -EFAULT; break; } for (i = c >> 2; i--; ) fb_writel(*src++, dst++); if (c & 3) { u8 *src8 = (u8 *) src; u8 __iomem *dst8 = (u8 __iomem *) dst; for (i = c & 3; i--; ) fb_writeb(*src8++, dst8++); dst = (u32 __iomem *) dst8; } *ppos += c; buf += c; cnt += c; count -= c; } kfree(buffer); return (cnt) ? cnt : err;}#ifdef CONFIG_KMODstatic void try_to_load(int fb){ request_module("fb%d", fb);}#endif /* CONFIG_KMOD */intfb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var){ struct fb_fix_screeninfo *fix = &info->fix; int xoffset = var->xoffset; int yoffset = var->yoffset; int err = 0, yres = info->var.yres; if (var->yoffset > 0) { if (var->vmode & FB_VMODE_YWRAP) { if (!fix->ywrapstep || (var->yoffset % fix->ywrapstep)) err = -EINVAL; else yres = 0; } else if (!fix->ypanstep || (var->yoffset % fix->ypanstep)) err = -EINVAL; } if (var->xoffset > 0 && (!fix->xpanstep || (var->xoffset % fix->xpanstep))) err = -EINVAL; if (err || !info->fbops->fb_pan_display || xoffset < 0 || yoffset < 0 || var->yoffset + yres > info->var.yres_virtual || var->xoffset + info->var.xres > info->var.xres_virtual) return -EINVAL; if ((err = info->fbops->fb_pan_display(var, info))) return err; info->var.xoffset = var->xoffset; info->var.yoffset = var->yoffset; if (var->vmode & FB_VMODE_YWRAP) info->var.vmode |= FB_VMODE_YWRAP; else info->var.vmode &= ~FB_VMODE_YWRAP; return 0;}static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, u32 activate){ struct fb_event event; struct fb_blit_caps caps, fbcaps; int err = 0; memset(&caps, 0, sizeof(caps)); memset(&fbcaps, 0, sizeof(fbcaps)); caps.flags = (activate & FB_ACTIVATE_ALL) ? 1 : 0; event.info = info; event.data = ∩︀ fb_notifier_call_chain(FB_EVENT_GET_REQ, &event); info->fbops->fb_get_caps(info, &fbcaps, var); if (((fbcaps.x ^ caps.x) & caps.x) || ((fbcaps.y ^ caps.y) & caps.y) || (fbcaps.len < caps.len)) err = -EINVAL; return err;}intfb_set_var(struct fb_info *info, struct fb_var_screeninfo *var){ int flags = info->flags; int ret = 0; if (var->activate & FB_ACTIVATE_INV_MODE) { struct fb_videomode mode1, mode2; fb_var_to_videomode(&mode1, var); fb_var_to_videomode(&mode2, &info->var); /* make sure we don't delete the videomode of current var */ ret = fb_mode_is_equal(&mode1, &mode2); if (!ret) { struct fb_event event; event.info = info; event.data = &mode1; ret = fb_notifier_call_chain(FB_EVENT_MODE_DELETE, &event); } if (!ret) fb_delete_videomode(&mode1, &info->modelist); ret = (ret) ? -EINVAL : 0; goto done; } if ((var->activate & FB_ACTIVATE_FORCE) || memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) { u32 activate = var->activate; if (!info->fbops->fb_check_var) { *var = info->var; goto done; } ret = info->fbops->fb_check_var(var, info); if (ret) goto done; if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { struct fb_videomode mode; if (info->fbops->fb_get_caps) { ret = fb_check_caps(info, var, activate); if (ret) goto done; } info->var = *var; if (info->fbops->fb_set_par) info->fbops->fb_set_par(info); fb_pan_display(info, &info->var); fb_set_cmap(&info->cmap, info); fb_var_to_videomode(&mode, &info->var); if (info->modelist.prev && info->modelist.next && !list_empty(&info->modelist)) ret = fb_add_videomode(&mode, &info->modelist); if (!ret && (flags & FBINFO_MISC_USEREVENT)) { struct fb_event event; int evnt = (activate & FB_ACTIVATE_ALL) ? FB_EVENT_MODE_CHANGE_ALL : FB_EVENT_MODE_CHANGE; info->flags &= ~FBINFO_MISC_USEREVENT; event.info = info; fb_notifier_call_chain(evnt, &event); } } } done: return ret;}intfb_blank(struct fb_info *info, int blank){ int ret = -EINVAL; if (blank > FB_BLANK_POWERDOWN) blank = FB_BLANK_POWERDOWN; if (info->fbops->fb_blank) ret = info->fbops->fb_blank(blank, info); if (!ret) { struct fb_event event; event.info = info; event.data = ␣ fb_notifier_call_chain(FB_EVENT_BLANK, &event); } return ret;}static int fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; struct fb_ops *fb = info->fbops; struct fb_var_screeninfo var; struct fb_fix_screeninfo fix; struct fb_con2fbmap con2fb; struct fb_cmap_user cmap; struct fb_event event; void __user *argp = (void __user *)arg; int i; int dyf; if (!fb) return -ENODEV; switch (cmd) { case FBIOGET_VSCREENINFO: return copy_to_user(argp, &info->var, sizeof(var)) ? -EFAULT : 0; case FBIOPUT_VSCREENINFO: if (copy_from_user(&var, argp, sizeof(var))) return -EFAULT; acquire_console_sem(); info->flags |= FBINFO_MISC_USEREVENT; i = fb_set_var(info, &var); info->flags &= ~FBINFO_MISC_USEREVENT; release_console_sem(); if (i) return i; if (copy_to_user(argp, &var, sizeof(var))) return -EFAULT; return 0; case FBIOGET_FSCREENINFO: return copy_to_user(argp, &info->fix, sizeof(fix)) ? -EFAULT : 0; //add by dyfFBIO_DYF //case FBIOSETBACKLIGHT: case FBIO_DYF: //if (copy_from_user(&dyf, argp, sizeof(var))) //return -EFAULT; if(arg==1) printk("arg=1 in fbmem.c"); else if(arg==2) printk("arg=2 in fbmem.c"); else printk("arg=other in fbmem.c"); printk("test FBIOSETBACKLIGHT in fbmem.c dyf"); /*if (copy_from_user(&cmap, argp, sizeof(cmap))) return -EFAULT; return copy_to_user(argp, &info->fix, sizeof(fix)) ? -EFAULT : 0;;*/ case FBIOPUTCMAP: if (copy_from_user(&cmap, argp, sizeof(cmap))) return -EFAULT; return (fb_set_user_cmap(&cmap, info)); case FBIOGETCMAP: if (copy_from_user(&cmap, argp, sizeof(cmap))) return -EFAULT; return fb_cmap_to_user(&info->cmap, &cmap); case FBIOPAN_DISPLAY: if (copy_from_user(&var, argp, sizeof(var))) return -EFAULT; acquire_console_sem(); i = fb_pan_display(info, &var); release_console_sem(); if (i) return i; if (copy_to_user(argp, &var, sizeof(var))) return -EFAULT; return 0; case FBIO_CURSOR: return -EINVAL; case FBIOGET_CON2FBMAP: if (copy_from_user(&con2fb, argp, sizeof(con2fb))) return -EFAULT; if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) return -EINVAL; con2fb.framebuffer = -1; event.info = info; event.data = &con2fb; fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); return copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; case FBIOPUT_CON2FBMAP: if (copy_from_user(&con2fb, argp, sizeof(con2fb))) return - EFAULT; if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES) return -EINVAL; if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) return -EINVAL;#ifdef CONFIG_KMOD if (!registered_fb[con2fb.framebuffer]) try_to_load(con2fb.framebuffer);#endif /* CONFIG_KMOD */ if (!registered_fb[con2fb.framebuffer]) return -EINVAL; event.info = info; event.data = &con2fb; return fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); case FBIOBLANK: acquire_console_sem(); info->flags |= FBINFO_MISC_USEREVENT; i = fb_blank(info, arg); info->flags &= ~FBINFO_MISC_USEREVENT; release_console_sem(); return i; default: if (fb->fb_ioctl == NULL) return -EINVAL; return fb->fb_ioctl(info, cmd, arg); }}#ifdef CONFIG_COMPATstruct fb_fix_screeninfo32 { char id[16]; compat_caddr_t smem_start; u32 smem_len; u32 type; u32 type_aux; u32 visual; u16 xpanstep; u16 ypanstep; u16 ywrapstep; u32 line_length; compat_caddr_t mmio_start; u32 mmio_len; u32 accel; u16 reserved[3];};struct fb_cmap32 { u32 start; u32 len; compat_caddr_t red; compat_caddr_t green; compat_caddr_t blue; compat_caddr_t transp;};static int fb_getput_cmap(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ struct fb_cmap_user __user *cmap; struct fb_cmap32 __user *cmap32; __u32 data; int err; cmap = compat_alloc_user_space(sizeof(*cmap)); cmap32 = compat_ptr(arg); if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32))) return -EFAULT; if (get_user(data, &cmap32->red) || put_user(compat_ptr(data), &cmap->red) || get_user(data, &cmap32->green) || put_user(compat_ptr(data), &cmap->green) || get_user(data, &cmap32->blue) || put_user(compat_ptr(data), &cmap->blue) || get_user(data, &cmap32->transp) || put_user(compat_ptr(data), &cmap->transp)) return -EFAULT; err = fb_ioctl(inode, file, cmd, (unsigned long) cmap); if (!err) { if (copy_in_user(&cmap32->start, &cmap->start, 2 * sizeof(__u32))) err = -EFAULT; } return err;}static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix, struct fb_fix_screeninfo32 __user *fix32){ __u32 data; int err; err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id)); data = (__u32) (unsigned long) fix->smem_start; err |= put_user(data, &fix32->smem_start);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -