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