Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * linux/drivers/video/fb_sys_read.c - Generic file operations where
0003  * framebuffer is in system RAM
0004  *
0005  * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
0006  *
0007  * This file is subject to the terms and conditions of the GNU General Public
0008  * License.  See the file COPYING in the main directory of this archive
0009  * for more details.
0010  *
0011  */
0012 #include <linux/fb.h>
0013 #include <linux/module.h>
0014 #include <linux/uaccess.h>
0015 
0016 ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
0017             loff_t *ppos)
0018 {
0019     unsigned long p = *ppos;
0020     void *src;
0021     int err = 0;
0022     unsigned long total_size;
0023 
0024     if (info->state != FBINFO_STATE_RUNNING)
0025         return -EPERM;
0026 
0027     total_size = info->screen_size;
0028 
0029     if (total_size == 0)
0030         total_size = info->fix.smem_len;
0031 
0032     if (p >= total_size)
0033         return 0;
0034 
0035     if (count >= total_size)
0036         count = total_size;
0037 
0038     if (count + p > total_size)
0039         count = total_size - p;
0040 
0041     src = (void __force *)(info->screen_base + p);
0042 
0043     if (info->fbops->fb_sync)
0044         info->fbops->fb_sync(info);
0045 
0046     if (copy_to_user(buf, src, count))
0047         err = -EFAULT;
0048 
0049     if  (!err)
0050         *ppos += count;
0051 
0052     return (err) ? err : count;
0053 }
0054 EXPORT_SYMBOL_GPL(fb_sys_read);
0055 
0056 ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
0057              size_t count, loff_t *ppos)
0058 {
0059     unsigned long p = *ppos;
0060     void *dst;
0061     int err = 0;
0062     unsigned long total_size;
0063 
0064     if (info->state != FBINFO_STATE_RUNNING)
0065         return -EPERM;
0066 
0067     total_size = info->screen_size;
0068 
0069     if (total_size == 0)
0070         total_size = info->fix.smem_len;
0071 
0072     if (p > total_size)
0073         return -EFBIG;
0074 
0075     if (count > total_size) {
0076         err = -EFBIG;
0077         count = total_size;
0078     }
0079 
0080     if (count + p > total_size) {
0081         if (!err)
0082             err = -ENOSPC;
0083 
0084         count = total_size - p;
0085     }
0086 
0087     dst = (void __force *) (info->screen_base + p);
0088 
0089     if (info->fbops->fb_sync)
0090         info->fbops->fb_sync(info);
0091 
0092     if (copy_from_user(dst, buf, count))
0093         err = -EFAULT;
0094 
0095     if  (!err)
0096         *ppos += count;
0097 
0098     return (err) ? err : count;
0099 }
0100 EXPORT_SYMBOL_GPL(fb_sys_write);
0101 
0102 MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
0103 MODULE_DESCRIPTION("Generic file read (fb in system RAM)");
0104 MODULE_LICENSE("GPL");