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#include <linux/fb.h> 13#include <linux/module.h> 14#include <linux/uaccess.h> 15 16ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count, 17 loff_t *ppos) 18{ 19 unsigned long p = *ppos; 20 void *src; 21 int err = 0; 22 unsigned long total_size, c; 23 ssize_t ret; 24 25 if (!(info->flags & FBINFO_VIRTFB)) 26 fb_warn_once(info, "Framebuffer is not in virtual address space."); 27 28 if (!info->screen_buffer) 29 return -ENODEV; 30 31 total_size = info->screen_size; 32 33 if (total_size == 0) 34 total_size = info->fix.smem_len; 35 36 if (p >= total_size) 37 return 0; 38 39 if (count >= total_size) 40 count = total_size; 41 42 if (count + p > total_size) 43 count = total_size - p; 44 45 src = info->screen_buffer + p; 46 47 if (info->fbops->fb_sync) 48 info->fbops->fb_sync(info); 49 50 c = copy_to_user(buf, src, count); 51 if (c) 52 err = -EFAULT; 53 ret = count - c; 54 55 *ppos += ret; 56 57 return ret ? ret : err; 58} 59EXPORT_SYMBOL_GPL(fb_sys_read); 60 61ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, 62 size_t count, loff_t *ppos) 63{ 64 unsigned long p = *ppos; 65 void *dst; 66 int err = 0; 67 unsigned long total_size, c; 68 size_t ret; 69 70 if (!(info->flags & FBINFO_VIRTFB)) 71 fb_warn_once(info, "Framebuffer is not in virtual address space."); 72 73 if (!info->screen_buffer) 74 return -ENODEV; 75 76 total_size = info->screen_size; 77 78 if (total_size == 0) 79 total_size = info->fix.smem_len; 80 81 if (p > total_size) 82 return -EFBIG; 83 84 if (count > total_size) { 85 err = -EFBIG; 86 count = total_size; 87 } 88 89 if (count + p > total_size) { 90 if (!err) 91 err = -ENOSPC; 92 93 count = total_size - p; 94 } 95 96 dst = info->screen_buffer + p; 97 98 if (info->fbops->fb_sync) 99 info->fbops->fb_sync(info); 100 101 c = copy_from_user(dst, buf, count); 102 if (c) 103 err = -EFAULT; 104 ret = count - c; 105 106 *ppos += ret; 107 108 return ret ? ret : err; 109} 110EXPORT_SYMBOL_GPL(fb_sys_write); 111 112MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); 113MODULE_DESCRIPTION("Generic file read (fb in system RAM)"); 114MODULE_LICENSE("GPL"); 115