免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4392 | 回复: 1
打印 上一主题 下一主题

[驱动] fb_ioctl函数的FBIOGETCMAP疑问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-09-05 22:39 |只看该作者 |倒序浏览
drivers/video/fbmem.c文件的fb_ioctl()函数如下:
但是关于
        case FBIOGETCMAP:
                if (copy_from_user(&cmap, argp, sizeof(cmap)))
                        return -EFAULT;
                return fb_cmap_to_user(&info->cmap, &cmap);

这部分代码我就看不懂了,不知道什么意思。望高人指点!
我觉得这样似乎更合乎情理呀
        case FBIOGETCMAP:
                if (fb_cmap_to_user(&info->cmap, &cmap))
                        return -EFAULT;
                return copy_to_user(argp, &cmap,  sizeof(cmap))


====
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;
       
        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;
        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 < 1 || 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);
        }
}

论坛徽章:
0
2 [报告]
发表于 2014-05-12 14:19 |只看该作者
因为 struct fb_cmap_user中,
struct fb_cmap_user {
        __u32 start;                        /* First entry        */
        __u32 len;                        /* Number of entries */
        __u16 __user *red;                /* Red values        */
        __u16 __user *green;
        __u16 __user *blue;
        __u16 __user *transp;                /* transparency, can be NULL */
};
后面是四个指向用户空间的指针,而指针的值,在前面copy_from_user的时候设置了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP