at master 116 lines 2.3 kB view raw
1/* 2 * linux/drivers/video/fb_sys_read.c - Generic file operations where 3 * framebuffer is in system RAM 4 * 5 * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net> 6 * 7 * This file is subject to the terms and conditions of the GNU General Public 8 * License. See the file COPYING in the main directory of this archive 9 * for more details. 10 * 11 */ 12 13#include <linux/export.h> 14#include <linux/fb.h> 15#include <linux/module.h> 16#include <linux/uaccess.h> 17 18ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count, 19 loff_t *ppos) 20{ 21 unsigned long p = *ppos; 22 void *src; 23 int err = 0; 24 unsigned long total_size, c; 25 ssize_t ret; 26 27 if (!(info->flags & FBINFO_VIRTFB)) 28 fb_warn_once(info, "Framebuffer is not in virtual address space."); 29 30 if (!info->screen_buffer) 31 return -ENODEV; 32 33 total_size = info->screen_size; 34 35 if (total_size == 0) 36 total_size = info->fix.smem_len; 37 38 if (p >= total_size) 39 return 0; 40 41 if (count >= total_size) 42 count = total_size; 43 44 if (count + p > total_size) 45 count = total_size - p; 46 47 src = info->screen_buffer + p; 48 49 if (info->fbops->fb_sync) 50 info->fbops->fb_sync(info); 51 52 c = copy_to_user(buf, src, count); 53 if (c) 54 err = -EFAULT; 55 ret = count - c; 56 57 *ppos += ret; 58 59 return ret ? ret : err; 60} 61EXPORT_SYMBOL_GPL(fb_sys_read); 62 63ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, 64 size_t count, loff_t *ppos) 65{ 66 unsigned long p = *ppos; 67 void *dst; 68 int err = 0; 69 unsigned long total_size, c; 70 size_t ret; 71 72 if (!(info->flags & FBINFO_VIRTFB)) 73 fb_warn_once(info, "Framebuffer is not in virtual address space."); 74 75 if (!info->screen_buffer) 76 return -ENODEV; 77 78 total_size = info->screen_size; 79 80 if (total_size == 0) 81 total_size = info->fix.smem_len; 82 83 if (p > total_size) 84 return -EFBIG; 85 86 if (count > total_size) { 87 err = -EFBIG; 88 count = total_size; 89 } 90 91 if (count + p > total_size) { 92 if (!err) 93 err = -ENOSPC; 94 95 count = total_size - p; 96 } 97 98 dst = info->screen_buffer + p; 99 100 if (info->fbops->fb_sync) 101 info->fbops->fb_sync(info); 102 103 c = copy_from_user(dst, buf, count); 104 if (c) 105 err = -EFAULT; 106 ret = count - c; 107 108 *ppos += ret; 109 110 return ret ? ret : err; 111} 112EXPORT_SYMBOL_GPL(fb_sys_write); 113 114MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); 115MODULE_DESCRIPTION("Generic file read (fb in system RAM)"); 116MODULE_LICENSE("GPL");