Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fb_sys_fops.c
Go to the documentation of this file.
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 <[email protected]>
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;
23 
24  if (info->state != FBINFO_STATE_RUNNING)
25  return -EPERM;
26 
27  total_size = info->screen_size;
28 
29  if (total_size == 0)
30  total_size = info->fix.smem_len;
31 
32  if (p >= total_size)
33  return 0;
34 
35  if (count >= total_size)
36  count = total_size;
37 
38  if (count + p > total_size)
39  count = total_size - p;
40 
41  src = (void __force *)(info->screen_base + p);
42 
43  if (info->fbops->fb_sync)
44  info->fbops->fb_sync(info);
45 
46  if (copy_to_user(buf, src, count))
47  err = -EFAULT;
48 
49  if (!err)
50  *ppos += count;
51 
52  return (err) ? err : count;
53 }
55 
56 ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
57  size_t count, loff_t *ppos)
58 {
59  unsigned long p = *ppos;
60  void *dst;
61  int err = 0;
62  unsigned long total_size;
63 
64  if (info->state != FBINFO_STATE_RUNNING)
65  return -EPERM;
66 
67  total_size = info->screen_size;
68 
69  if (total_size == 0)
70  total_size = info->fix.smem_len;
71 
72  if (p > total_size)
73  return -EFBIG;
74 
75  if (count > total_size) {
76  err = -EFBIG;
77  count = total_size;
78  }
79 
80  if (count + p > total_size) {
81  if (!err)
82  err = -ENOSPC;
83 
84  count = total_size - p;
85  }
86 
87  dst = (void __force *) (info->screen_base + p);
88 
89  if (info->fbops->fb_sync)
90  info->fbops->fb_sync(info);
91 
92  if (copy_from_user(dst, buf, count))
93  err = -EFAULT;
94 
95  if (!err)
96  *ppos += count;
97 
98  return (err) ? err : count;
99 }
101 
102 MODULE_AUTHOR("Antonino Daplas <[email protected]>");
103 MODULE_DESCRIPTION("Generic file read (fb in system RAM)");
104 MODULE_LICENSE("GPL");